mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory. [Misc #13792] [ruby-core:82287] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
75bfc6440d
commit
1d15d5f080
4370 changed files with 0 additions and 0 deletions
19
spec/ruby/core/array/allocate_spec.rb
Normal file
19
spec/ruby/core/array/allocate_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array.allocate" do
|
||||
it "returns an instance of Array" do
|
||||
ary = Array.allocate
|
||||
ary.should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "returns a fully-formed instance of Array" do
|
||||
ary = Array.allocate
|
||||
ary.size.should == 0
|
||||
ary << 1
|
||||
ary.should == [1]
|
||||
end
|
||||
|
||||
it "does not accept any arguments" do
|
||||
lambda { Array.allocate(1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
37
spec/ruby/core/array/any_spec.rb
Normal file
37
spec/ruby/core/array/any_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#any?" do
|
||||
describe 'with no block given (a default block of { |x| x } is implicit)' do
|
||||
it "is false if the array is empty" do
|
||||
empty_array = []
|
||||
empty_array.any?.should == false
|
||||
end
|
||||
|
||||
it "is false if the array is not empty, but all the members of the array are falsy" do
|
||||
falsy_array = [false, nil, false]
|
||||
falsy_array.any?.should == false
|
||||
end
|
||||
|
||||
it "is true if the array has any truthy members" do
|
||||
not_empty_array = ['anything', nil]
|
||||
not_empty_array.any?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with a block given' do
|
||||
it 'is false if the array is empty' do
|
||||
empty_array = []
|
||||
empty_array.any? {|v| 1 == 1 }.should == false
|
||||
end
|
||||
|
||||
it 'is true if the block returns true for any member of the array' do
|
||||
array_with_members = [false, false, true, false]
|
||||
array_with_members.any? {|v| v == true }.should == true
|
||||
end
|
||||
|
||||
it 'is false if the block returns false for all members of the array' do
|
||||
array_with_members = [false, false, true, false]
|
||||
array_with_members.any? {|v| v == 42 }.should == false
|
||||
end
|
||||
end
|
||||
end
|
35
spec/ruby/core/array/append_spec.rb
Normal file
35
spec/ruby/core/array/append_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#<<" do
|
||||
it "pushes the object onto the end of the array" do
|
||||
([ 1, 2 ] << "c" << "d" << [ 3, 4 ]).should == [1, 2, "c", "d", [3, 4]]
|
||||
end
|
||||
|
||||
it "returns self to allow chaining" do
|
||||
a = []
|
||||
b = a
|
||||
(a << 1).should equal(b)
|
||||
(a << 2 << 3).should equal(b)
|
||||
end
|
||||
|
||||
it "correctly resizes the Array" do
|
||||
a = []
|
||||
a.size.should == 0
|
||||
a << :foo
|
||||
a.size.should == 1
|
||||
a << :bar << :baz
|
||||
a.size.should == 3
|
||||
|
||||
a = [1, 2, 3]
|
||||
a.shift
|
||||
a.shift
|
||||
a.shift
|
||||
a << :foo
|
||||
a.should == [:foo]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array << 5 }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
7
spec/ruby/core/array/array_spec.rb
Normal file
7
spec/ruby/core/array/array_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array" do
|
||||
it "includes Enumerable" do
|
||||
Array.include?(Enumerable).should == true
|
||||
end
|
||||
end
|
40
spec/ruby/core/array/assoc_spec.rb
Normal file
40
spec/ruby/core/array/assoc_spec.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#assoc" do
|
||||
it "returns the first array whose 1st item is == obj or nil" do
|
||||
s1 = ["colors", "red", "blue", "green"]
|
||||
s2 = [:letters, "a", "b", "c"]
|
||||
s3 = [4]
|
||||
s4 = ["colors", "cyan", "yellow", "magenda"]
|
||||
s5 = [:letters, "a", "i", "u"]
|
||||
s_nil = [nil, nil]
|
||||
a = [s1, s2, s3, s4, s5, s_nil]
|
||||
a.assoc(s1.first).should equal(s1)
|
||||
a.assoc(s2.first).should equal(s2)
|
||||
a.assoc(s3.first).should equal(s3)
|
||||
a.assoc(s4.first).should equal(s1)
|
||||
a.assoc(s5.first).should equal(s2)
|
||||
a.assoc(s_nil.first).should equal(s_nil)
|
||||
a.assoc(4).should equal(s3)
|
||||
a.assoc("key not in array").should be_nil
|
||||
end
|
||||
|
||||
it "calls == on first element of each array" do
|
||||
key1 = 'it'
|
||||
key2 = mock('key2')
|
||||
items = [['not it', 1], [ArraySpecs::AssocKey.new, 2], ['na', 3]]
|
||||
|
||||
items.assoc(key1).should equal(items[1])
|
||||
items.assoc(key2).should be_nil
|
||||
end
|
||||
|
||||
it "ignores any non-Array elements" do
|
||||
[1, 2, 3].assoc(2).should be_nil
|
||||
s1 = [4]
|
||||
s2 = [5, 4, 3]
|
||||
a = ["foo", [], s1, s2, nil, []]
|
||||
a.assoc(s1.first).should equal(s1)
|
||||
a.assoc(s2.first).should equal(s2)
|
||||
end
|
||||
end
|
56
spec/ruby/core/array/at_spec.rb
Normal file
56
spec/ruby/core/array/at_spec.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#at" do
|
||||
it "returns the (n+1)'th element for the passed index n" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a.at(0).should == 1
|
||||
a.at(1).should == 2
|
||||
a.at(5).should == 6
|
||||
end
|
||||
|
||||
it "returns nil if the given index is greater than or equal to the array's length" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a.at(6).should == nil
|
||||
a.at(7).should == nil
|
||||
end
|
||||
|
||||
it "returns the (-n)'th elemet from the last, for the given negative index n" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a.at(-1).should == 6
|
||||
a.at(-2).should == 5
|
||||
a.at(-6).should == 1
|
||||
end
|
||||
|
||||
it "returns nil if the given index is less than -len, where len is length of the array" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a.at(-7).should == nil
|
||||
a.at(-8).should == nil
|
||||
end
|
||||
|
||||
it "does not extend the array unless the given index is out of range" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a.length.should == 6
|
||||
a.at(100)
|
||||
a.length.should == 6
|
||||
a.at(-100)
|
||||
a.length.should == 6
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Integer using #to_int" do
|
||||
a = ["a", "b", "c"]
|
||||
a.at(0.5).should == "a"
|
||||
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
a.at(obj).should == "c"
|
||||
end
|
||||
|
||||
it "raises a TypeError when the passed argument can't be coerced to Integer" do
|
||||
lambda { [].at("cat") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when 2 or more arguments is passed" do
|
||||
lambda { [:a, :b].at(0,1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
87
spec/ruby/core/array/bsearch_index_spec.rb
Normal file
87
spec/ruby/core/array/bsearch_index_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
ruby_version_is "2.3" do
|
||||
describe "Array#bsearch_index" do
|
||||
context "when not passed a block" do
|
||||
before :each do
|
||||
@enum = [1, 2, 42, 100, 666].bsearch_index
|
||||
end
|
||||
|
||||
it "returns an Enumerator" do
|
||||
@enum.should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "returns an Enumerator with unknown size" do
|
||||
@enum.size.should be_nil
|
||||
end
|
||||
|
||||
it "returns index of element when block condition is satisfied" do
|
||||
@enum.each { |x| x >= 33 }.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a TypeError when block returns a String" do
|
||||
lambda { [1, 2, 3].bsearch_index { "not ok" } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns nil when block is empty" do
|
||||
[1, 2, 3].bsearch_index {}.should be_nil
|
||||
end
|
||||
|
||||
context "minimum mode" do
|
||||
before :each do
|
||||
@array = [0, 4, 7, 10, 12]
|
||||
end
|
||||
|
||||
it "returns index of first element which satisfies the block" do
|
||||
@array.bsearch_index { |x| x >= 4 }.should == 1
|
||||
@array.bsearch_index { |x| x >= 6 }.should == 2
|
||||
@array.bsearch_index { |x| x >= -1 }.should == 0
|
||||
end
|
||||
|
||||
it "returns nil when block condition is never satisfied" do
|
||||
@array.bsearch_index { false }.should be_nil
|
||||
@array.bsearch_index { |x| x >= 100 }.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "find any mode" do
|
||||
before :each do
|
||||
@array = [0, 4, 7, 10, 12]
|
||||
end
|
||||
|
||||
it "returns the index of any matched elements where element is between 4 <= x < 8" do
|
||||
[1, 2].should include(@array.bsearch_index { |x| 1 - x / 4 })
|
||||
end
|
||||
|
||||
it "returns the index of any matched elements where element is between 8 <= x < 10" do
|
||||
@array.bsearch_index { |x| 4 - x / 2 }.should be_nil
|
||||
end
|
||||
|
||||
it "returns nil when block never returns 0" do
|
||||
@array.bsearch_index { |x| 1 }.should be_nil
|
||||
@array.bsearch_index { |x| -1 }.should be_nil
|
||||
end
|
||||
|
||||
it "returns the middle element when block always returns zero" do
|
||||
@array.bsearch_index { |x| 0 }.should == 2
|
||||
end
|
||||
|
||||
context "magnitude does not effect the result" do
|
||||
it "returns the index of any matched elements where element is between 4n <= xn < 8n" do
|
||||
[1, 2].should include(@array.bsearch_index { |x| (1 - x / 4) * (2**100) })
|
||||
end
|
||||
|
||||
it "returns nil when block never returns 0" do
|
||||
@array.bsearch_index { |x| 1 * (2**100) }.should be_nil
|
||||
@array.bsearch_index { |x| (-1) * (2**100) }.should be_nil
|
||||
end
|
||||
|
||||
it "handles values from Bignum#coerce" do
|
||||
[1, 2].should include(@array.bsearch_index { |x| (2**100).coerce((1 - x / 4) * (2**100)).first })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
84
spec/ruby/core/array/bsearch_spec.rb
Normal file
84
spec/ruby/core/array/bsearch_spec.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
describe "Array#bsearch" do
|
||||
it "returns an Enumerator when not passed a block" do
|
||||
[1].bsearch.should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorized_with_unknown_size, :bsearch, [1,2,3]
|
||||
|
||||
it "raises a TypeError if the block returns an Object" do
|
||||
lambda { [1].bsearch { Object.new } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if the block returns a String" do
|
||||
lambda { [1].bsearch { "1" } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
context "with a block returning true or false" do
|
||||
it "returns nil if the block returns false for every element" do
|
||||
[0, 1, 2, 3].bsearch { |x| x > 3 }.should be_nil
|
||||
end
|
||||
|
||||
it "returns nil if the block returns nil for every element" do
|
||||
[0, 1, 2, 3].bsearch { |x| nil }.should be_nil
|
||||
end
|
||||
|
||||
it "returns element at zero if the block returns true for every element" do
|
||||
[0, 1, 2, 3].bsearch { |x| x < 4 }.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "returns the element at the smallest index for which block returns true" do
|
||||
[0, 1, 3, 4].bsearch { |x| x >= 2 }.should == 3
|
||||
[0, 1, 3, 4].bsearch { |x| x >= 1 }.should == 1
|
||||
end
|
||||
end
|
||||
|
||||
context "with a block returning negative, zero, positive numbers" do
|
||||
it "returns nil if the block returns less than zero for every element" do
|
||||
[0, 1, 2, 3].bsearch { |x| x <=> 5 }.should be_nil
|
||||
end
|
||||
|
||||
it "returns nil if the block returns greater than zero for every element" do
|
||||
[0, 1, 2, 3].bsearch { |x| x <=> -1 }.should be_nil
|
||||
|
||||
end
|
||||
|
||||
it "returns nil if the block never returns zero" do
|
||||
[0, 1, 3, 4].bsearch { |x| x <=> 2 }.should be_nil
|
||||
end
|
||||
|
||||
it "accepts (+/-)Float::INFINITY from the block" do
|
||||
[0, 1, 3, 4].bsearch { |x| Float::INFINITY }.should be_nil
|
||||
[0, 1, 3, 4].bsearch { |x| -Float::INFINITY }.should be_nil
|
||||
end
|
||||
|
||||
it "returns an element at an index for which block returns 0.0" do
|
||||
result = [0, 1, 2, 3, 4].bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 }
|
||||
result.should == 2
|
||||
end
|
||||
|
||||
it "returns an element at an index for which block returns 0" do
|
||||
result = [0, 1, 2, 3, 4].bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 }
|
||||
[1, 2].should include(result)
|
||||
end
|
||||
end
|
||||
|
||||
context "with a block that calls break" do
|
||||
it "returns nil if break is called without a value" do
|
||||
['a', 'b', 'c'].bsearch { |v| break }.should be_nil
|
||||
end
|
||||
|
||||
it "returns nil if break is called with a nil value" do
|
||||
['a', 'b', 'c'].bsearch { |v| break nil }.should be_nil
|
||||
end
|
||||
|
||||
it "returns object if break is called with an object" do
|
||||
['a', 'b', 'c'].bsearch { |v| break 1234 }.should == 1234
|
||||
['a', 'b', 'c'].bsearch { |v| break 'hi' }.should == 'hi'
|
||||
['a', 'b', 'c'].bsearch { |v| break [42] }.should == [42]
|
||||
end
|
||||
end
|
||||
end
|
49
spec/ruby/core/array/clear_spec.rb
Normal file
49
spec/ruby/core/array/clear_spec.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#clear" do
|
||||
it "removes all elements" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.clear.should equal(a)
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
a = [1]
|
||||
oid = a.object_id
|
||||
a.clear.object_id.should == oid
|
||||
end
|
||||
|
||||
it "leaves the Array empty" do
|
||||
a = [1]
|
||||
a.clear
|
||||
a.empty?.should == true
|
||||
a.size.should == 0
|
||||
end
|
||||
|
||||
it "keeps tainted status" do
|
||||
a = [1]
|
||||
a.taint
|
||||
a.tainted?.should be_true
|
||||
a.clear
|
||||
a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "does not accept any arguments" do
|
||||
lambda { [1].clear(true) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
a = [1]
|
||||
a.untrust
|
||||
a.untrusted?.should be_true
|
||||
a.clear
|
||||
a.untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
a = [1]
|
||||
a.freeze
|
||||
lambda { a.clear }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
31
spec/ruby/core/array/clone_spec.rb
Normal file
31
spec/ruby/core/array/clone_spec.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/clone', __FILE__)
|
||||
|
||||
describe "Array#clone" do
|
||||
it_behaves_like :array_clone, :clone
|
||||
|
||||
it "copies frozen status from the original" do
|
||||
a = [1, 2, 3, 4]
|
||||
b = [1, 2, 3, 4]
|
||||
a.freeze
|
||||
aa = a.clone
|
||||
bb = b.clone
|
||||
|
||||
aa.frozen?.should == true
|
||||
bb.frozen?.should == false
|
||||
end
|
||||
|
||||
it "copies singleton methods" do
|
||||
a = [1, 2, 3, 4]
|
||||
b = [1, 2, 3, 4]
|
||||
def a.a_singleton_method; end
|
||||
aa = a.clone
|
||||
bb = b.clone
|
||||
|
||||
a.respond_to?(:a_singleton_method).should be_true
|
||||
b.respond_to?(:a_singleton_method).should be_false
|
||||
aa.respond_to?(:a_singleton_method).should be_true
|
||||
bb.respond_to?(:a_singleton_method).should be_false
|
||||
end
|
||||
end
|
11
spec/ruby/core/array/collect_spec.rb
Normal file
11
spec/ruby/core/array/collect_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/collect', __FILE__)
|
||||
|
||||
describe "Array#collect" do
|
||||
it_behaves_like(:array_collect, :collect)
|
||||
end
|
||||
|
||||
describe "Array#collect!" do
|
||||
it_behaves_like(:array_collect_b, :collect!)
|
||||
end
|
74
spec/ruby/core/array/combination_spec.rb
Normal file
74
spec/ruby/core/array/combination_spec.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#combination" do
|
||||
before :each do
|
||||
@array = [1, 2, 3, 4]
|
||||
end
|
||||
|
||||
it "returns an enumerator when no block is provided" do
|
||||
@array.combination(2).should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "returns self when a block is given" do
|
||||
@array.combination(2){}.should equal(@array)
|
||||
end
|
||||
|
||||
it "yields nothing for out of bounds length and return self" do
|
||||
@array.combination(5).to_a.should == []
|
||||
@array.combination(-1).to_a.should == []
|
||||
end
|
||||
|
||||
it "yields the expected combinations" do
|
||||
@array.combination(3).to_a.sort.should == [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
|
||||
end
|
||||
|
||||
it "yields nothing if the argument is out of bounds" do
|
||||
@array.combination(-1).to_a.should == []
|
||||
@array.combination(5).to_a.should == []
|
||||
end
|
||||
|
||||
it "yields a copy of self if the argument is the size of the receiver" do
|
||||
r = @array.combination(4).to_a
|
||||
r.should == [@array]
|
||||
r[0].should_not equal(@array)
|
||||
end
|
||||
|
||||
it "yields [] when length is 0" do
|
||||
@array.combination(0).to_a.should == [[]] # one combination of length 0
|
||||
[].combination(0).to_a.should == [[]] # one combination of length 0
|
||||
end
|
||||
|
||||
it "yields a partition consisting of only singletons" do
|
||||
@array.combination(1).to_a.sort.should == [[1],[2],[3],[4]]
|
||||
end
|
||||
|
||||
it "generates from a defensive copy, ignoring mutations" do
|
||||
accum = []
|
||||
@array.combination(2) do |x|
|
||||
accum << x
|
||||
@array[0] = 1
|
||||
end
|
||||
accum.should == [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "returns 0 when the number of combinations is < 0" do
|
||||
@array.combination(-1).size.should == 0
|
||||
[].combination(-2).size.should == 0
|
||||
end
|
||||
it "returns the binomial coeficient between the array size the number of combinations" do
|
||||
@array.combination(5).size.should == 0
|
||||
@array.combination(4).size.should == 1
|
||||
@array.combination(3).size.should == 4
|
||||
@array.combination(2).size.should == 6
|
||||
@array.combination(1).size.should == 4
|
||||
@array.combination(0).size.should == 1
|
||||
[].combination(0).size.should == 1
|
||||
[].combination(1).size.should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
77
spec/ruby/core/array/compact_spec.rb
Normal file
77
spec/ruby/core/array/compact_spec.rb
Normal file
|
@ -0,0 +1,77 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#compact" do
|
||||
it "returns a copy of array with all nil elements removed" do
|
||||
a = [1, 2, 4]
|
||||
a.compact.should == [1, 2, 4]
|
||||
a = [1, nil, 2, 4]
|
||||
a.compact.should == [1, 2, 4]
|
||||
a = [1, 2, 4, nil]
|
||||
a.compact.should == [1, 2, 4]
|
||||
a = [nil, 1, 2, 4]
|
||||
a.compact.should == [1, 2, 4]
|
||||
end
|
||||
|
||||
it "does not return self" do
|
||||
a = [1, 2, 3]
|
||||
a.compact.should_not equal(a)
|
||||
end
|
||||
|
||||
it "does not return subclass instance for Array subclasses" do
|
||||
ArraySpecs::MyArray[1, 2, 3, nil].compact.should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "does not keep tainted status even if all elements are removed" do
|
||||
a = [nil, nil]
|
||||
a.taint
|
||||
a.compact.tainted?.should be_false
|
||||
end
|
||||
|
||||
it "does not keep untrusted status even if all elements are removed" do
|
||||
a = [nil, nil]
|
||||
a.untrust
|
||||
a.compact.untrusted?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#compact!" do
|
||||
it "removes all nil elements" do
|
||||
a = ['a', nil, 'b', false, 'c']
|
||||
a.compact!.should equal(a)
|
||||
a.should == ["a", "b", false, "c"]
|
||||
a = [nil, 'a', 'b', false, 'c']
|
||||
a.compact!.should equal(a)
|
||||
a.should == ["a", "b", false, "c"]
|
||||
a = ['a', 'b', false, 'c', nil]
|
||||
a.compact!.should equal(a)
|
||||
a.should == ["a", "b", false, "c"]
|
||||
end
|
||||
|
||||
it "returns self if some nil elements are removed" do
|
||||
a = ['a', nil, 'b', false, 'c']
|
||||
a.compact!.object_id.should == a.object_id
|
||||
end
|
||||
|
||||
it "returns nil if there are no nil elements to remove" do
|
||||
[1, 2, false, 3].compact!.should == nil
|
||||
end
|
||||
|
||||
it "keeps tainted status even if all elements are removed" do
|
||||
a = [nil, nil]
|
||||
a.taint
|
||||
a.compact!
|
||||
a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "keeps untrusted status even if all elements are removed" do
|
||||
a = [nil, nil]
|
||||
a.untrust
|
||||
a.compact!
|
||||
a.untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.compact! }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
97
spec/ruby/core/array/comparison_spec.rb
Normal file
97
spec/ruby/core/array/comparison_spec.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#<=>" do
|
||||
it "calls <=> left to right and return first non-0 result" do
|
||||
[-1, +1, nil, "foobar"].each do |result|
|
||||
lhs = Array.new(3) { mock("#{result}") }
|
||||
rhs = Array.new(3) { mock("#{result}") }
|
||||
|
||||
lhs[0].should_receive(:<=>).with(rhs[0]).and_return(0)
|
||||
lhs[1].should_receive(:<=>).with(rhs[1]).and_return(result)
|
||||
lhs[2].should_not_receive(:<=>)
|
||||
|
||||
(lhs <=> rhs).should == result
|
||||
end
|
||||
end
|
||||
|
||||
it "returns 0 if the arrays are equal" do
|
||||
([] <=> []).should == 0
|
||||
([1, 2, 3, 4, 5, 6] <=> [1, 2, 3, 4, 5.0, 6.0]).should == 0
|
||||
end
|
||||
|
||||
it "returns -1 if the array is shorter than the other array" do
|
||||
([] <=> [1]).should == -1
|
||||
([1, 1] <=> [1, 1, 1]).should == -1
|
||||
end
|
||||
|
||||
it "returns +1 if the array is longer than the other array" do
|
||||
([1] <=> []).should == +1
|
||||
([1, 1, 1] <=> [1, 1]).should == +1
|
||||
end
|
||||
|
||||
it "returns -1 if the arrays have same length and a pair of corresponding elements returns -1 for <=>" do
|
||||
eq_l = mock('an object equal to the other')
|
||||
eq_r = mock('an object equal to the other')
|
||||
eq_l.should_receive(:<=>).with(eq_r).any_number_of_times.and_return(0)
|
||||
|
||||
less = mock('less than the other')
|
||||
greater = mock('greater then the other')
|
||||
less.should_receive(:<=>).with(greater).any_number_of_times.and_return(-1)
|
||||
|
||||
rest = mock('an rest element of the arrays')
|
||||
rest.should_receive(:<=>).with(rest).any_number_of_times.and_return(0)
|
||||
lhs = [eq_l, eq_l, less, rest]
|
||||
rhs = [eq_r, eq_r, greater, rest]
|
||||
|
||||
(lhs <=> rhs).should == -1
|
||||
end
|
||||
|
||||
it "returns +1 if the arrays have same length and a pair of corresponding elements returns +1 for <=>" do
|
||||
eq_l = mock('an object equal to the other')
|
||||
eq_r = mock('an object equal to the other')
|
||||
eq_l.should_receive(:<=>).with(eq_r).any_number_of_times.and_return(0)
|
||||
|
||||
greater = mock('greater then the other')
|
||||
less = mock('less than the other')
|
||||
greater.should_receive(:<=>).with(less).any_number_of_times.and_return(+1)
|
||||
|
||||
rest = mock('an rest element of the arrays')
|
||||
rest.should_receive(:<=>).with(rest).any_number_of_times.and_return(0)
|
||||
lhs = [eq_l, eq_l, greater, rest]
|
||||
rhs = [eq_r, eq_r, less, rest]
|
||||
|
||||
(lhs <=> rhs).should == +1
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
(empty <=> empty).should == 0
|
||||
(empty <=> []).should == 1
|
||||
([] <=> empty).should == -1
|
||||
|
||||
(ArraySpecs.recursive_array <=> []).should == 1
|
||||
([] <=> ArraySpecs.recursive_array).should == -1
|
||||
|
||||
(ArraySpecs.recursive_array <=> ArraySpecs.empty_recursive_array).should == nil
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
(array <=> array).should == 0
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Array using #to_ary" do
|
||||
obj = mock('to_ary')
|
||||
obj.stub!(:to_ary).and_return([1, 2, 3])
|
||||
([4, 5] <=> obj).should == ([4, 5] <=> obj.to_ary)
|
||||
end
|
||||
|
||||
it "does not call #to_ary on Array subclasses" do
|
||||
obj = ArraySpecs::ToAryArray[5, 6, 7]
|
||||
obj.should_not_receive(:to_ary)
|
||||
([5, 6, 7] <=> obj).should == 0
|
||||
end
|
||||
|
||||
it "returns nil when the argument is not array-like" do
|
||||
([] <=> false).should be_nil
|
||||
end
|
||||
end
|
132
spec/ruby/core/array/concat_spec.rb
Normal file
132
spec/ruby/core/array/concat_spec.rb
Normal file
|
@ -0,0 +1,132 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
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 RuntimeError when Array is frozen and modification occurs" do
|
||||
lambda { ArraySpecs.frozen_array.concat [1] }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError when Array is frozen and no modification occurs" do
|
||||
lambda { ArraySpecs.frozen_array.concat([]) }.should raise_error(RuntimeError)
|
||||
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
|
24
spec/ruby/core/array/constructor_spec.rb
Normal file
24
spec/ruby/core/array/constructor_spec.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array.[]" do
|
||||
it "returns a new array populated with the given elements" do
|
||||
obj = Object.new
|
||||
Array.[](5, true, nil, 'a', "Ruby", obj).should == [5, true, nil, "a", "Ruby", obj]
|
||||
|
||||
a = ArraySpecs::MyArray.[](5, true, nil, 'a', "Ruby", obj)
|
||||
a.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
a.inspect.should == [5, true, nil, "a", "Ruby", obj].inspect
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array[]" do
|
||||
it "is a synonym for .[]" do
|
||||
obj = Object.new
|
||||
Array[5, true, nil, 'a', "Ruby", obj].should == Array.[](5, true, nil, "a", "Ruby", obj)
|
||||
|
||||
a = ArraySpecs::MyArray[5, true, nil, 'a', "Ruby", obj]
|
||||
a.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
a.inspect.should == [5, true, nil, "a", "Ruby", obj].inspect
|
||||
end
|
||||
end
|
15
spec/ruby/core/array/count_spec.rb
Normal file
15
spec/ruby/core/array/count_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#count" do
|
||||
it "returns the number of elements" do
|
||||
[:a, :b, :c].count.should == 3
|
||||
end
|
||||
|
||||
it "returns the number of elements that equal the argument" do
|
||||
[:a, :b, :b, :c].count(:b).should == 2
|
||||
end
|
||||
|
||||
it "returns the number of element for which the block evaluates to true" do
|
||||
[:a, :b, :c].count { |s| s != :b }.should == 2
|
||||
end
|
||||
end
|
101
spec/ruby/core/array/cycle_spec.rb
Normal file
101
spec/ruby/core/array/cycle_spec.rb
Normal file
|
@ -0,0 +1,101 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
describe "Array#cycle" do
|
||||
before :each do
|
||||
ScratchPad.record []
|
||||
|
||||
@array = [1, 2, 3]
|
||||
@prc = lambda { |x| ScratchPad << x }
|
||||
end
|
||||
|
||||
it "does not yield and returns nil when the array is empty and passed value is an integer" do
|
||||
[].cycle(6, &@prc).should be_nil
|
||||
ScratchPad.recorded.should == []
|
||||
end
|
||||
|
||||
it "does not yield and returns nil when the array is empty and passed value is nil" do
|
||||
[].cycle(nil, &@prc).should be_nil
|
||||
ScratchPad.recorded.should == []
|
||||
end
|
||||
|
||||
it "does not yield and returns nil when passed 0" do
|
||||
@array.cycle(0, &@prc).should be_nil
|
||||
ScratchPad.recorded.should == []
|
||||
end
|
||||
|
||||
it "iterates the array 'count' times yielding each item to the block" do
|
||||
@array.cycle(2, &@prc)
|
||||
ScratchPad.recorded.should == [1, 2, 3, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "iterates indefinitely when not passed a count" do
|
||||
@array.cycle do |x|
|
||||
ScratchPad << x
|
||||
break if ScratchPad.recorded.size > 7
|
||||
end
|
||||
ScratchPad.recorded.should == [1, 2, 3, 1, 2, 3, 1, 2]
|
||||
end
|
||||
|
||||
it "iterates indefinitely when passed nil" do
|
||||
@array.cycle(nil) do |x|
|
||||
ScratchPad << x
|
||||
break if ScratchPad.recorded.size > 7
|
||||
end
|
||||
ScratchPad.recorded.should == [1, 2, 3, 1, 2, 3, 1, 2]
|
||||
end
|
||||
|
||||
it "does not rescue StopIteration when not passed a count" do
|
||||
lambda do
|
||||
@array.cycle { raise StopIteration }
|
||||
end.should raise_error(StopIteration)
|
||||
end
|
||||
|
||||
it "does not rescue StopIteration when passed a count" do
|
||||
lambda do
|
||||
@array.cycle(3) { raise StopIteration }
|
||||
end.should raise_error(StopIteration)
|
||||
end
|
||||
|
||||
it "iterates the array Integer(count) times when passed a Float count" do
|
||||
@array.cycle(2.7, &@prc)
|
||||
ScratchPad.recorded.should == [1, 2, 3, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "calls #to_int to convert count to an Integer" do
|
||||
count = mock("cycle count 2")
|
||||
count.should_receive(:to_int).and_return(2)
|
||||
|
||||
@array.cycle(count, &@prc)
|
||||
ScratchPad.recorded.should == [1, 2, 3, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_int does not return an Integer" do
|
||||
count = mock("cycle count 2")
|
||||
count.should_receive(:to_int).and_return("2")
|
||||
|
||||
lambda { @array.cycle(count, &@prc) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed a String" do
|
||||
lambda { @array.cycle("4") { } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed an Object" do
|
||||
lambda { @array.cycle(mock("cycle count")) { } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed true" do
|
||||
lambda { @array.cycle(true) { } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed false" do
|
||||
lambda { @array.cycle(false) { } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
before :all do
|
||||
@object = [1, 2, 3, 4]
|
||||
@empty_object = []
|
||||
end
|
||||
it_should_behave_like :enumeratorized_with_cycle_size
|
||||
end
|
61
spec/ruby/core/array/delete_at_spec.rb
Normal file
61
spec/ruby/core/array/delete_at_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#delete_at" do
|
||||
it "removes the element at the specified index" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.delete_at(2)
|
||||
a.should == [1, 2, 4]
|
||||
a.delete_at(-1)
|
||||
a.should == [1, 2]
|
||||
end
|
||||
|
||||
it "returns the removed element at the specified index" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.delete_at(2).should == 3
|
||||
a.delete_at(-1).should == 4
|
||||
end
|
||||
|
||||
it "returns nil and makes no modification if the index is out of range" do
|
||||
a = [1, 2]
|
||||
a.delete_at(3).should == nil
|
||||
a.should == [1, 2]
|
||||
a.delete_at(-3).should == nil
|
||||
a.should == [1, 2]
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Integer using #to_int" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(-1)
|
||||
[1, 2].delete_at(obj).should == 2
|
||||
end
|
||||
|
||||
it "accepts negative indices" do
|
||||
a = [1, 2]
|
||||
a.delete_at(-2).should == 1
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { [1,2,3].freeze.delete_at(0) }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "keeps tainted status" do
|
||||
ary = [1, 2]
|
||||
ary.taint
|
||||
ary.tainted?.should be_true
|
||||
ary.delete_at(0)
|
||||
ary.tainted?.should be_true
|
||||
ary.delete_at(0) # now empty
|
||||
ary.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
ary = [1, 2]
|
||||
ary.untrust
|
||||
ary.untrusted?.should be_true
|
||||
ary.delete_at(0)
|
||||
ary.untrusted?.should be_true
|
||||
ary.delete_at(0) # now empty
|
||||
ary.untrusted?.should be_true
|
||||
end
|
||||
end
|
66
spec/ruby/core/array/delete_if_spec.rb
Normal file
66
spec/ruby/core/array/delete_if_spec.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/enumeratorize', __FILE__)
|
||||
require File.expand_path('../shared/delete_if', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
describe "Array#delete_if" do
|
||||
before do
|
||||
@a = [ "a", "b", "c" ]
|
||||
end
|
||||
|
||||
it "removes each element for which block returns true" do
|
||||
@a = [ "a", "b", "c" ]
|
||||
@a.delete_if { |x| x >= "b" }
|
||||
@a.should == ["a"]
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
@a.delete_if{ true }.equal?(@a).should be_true
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorize, :delete_if
|
||||
|
||||
it "returns self when called on an Array emptied with #shift" do
|
||||
array = [1]
|
||||
array.shift
|
||||
array.delete_if { |x| true }.should equal(array)
|
||||
end
|
||||
|
||||
it "returns an Enumerator if no block given, and the enumerator can modify the original array" do
|
||||
enum = @a.delete_if
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
@a.should_not be_empty
|
||||
enum.each { true }
|
||||
@a.should be_empty
|
||||
end
|
||||
|
||||
it "returns an Enumerator if no block given, and the array is frozen" do
|
||||
@a.freeze.delete_if.should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.delete_if {} }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on an empty frozen array" do
|
||||
lambda { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "keeps tainted status" do
|
||||
@a.taint
|
||||
@a.tainted?.should be_true
|
||||
@a.delete_if{ true }
|
||||
@a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
@a.untrust
|
||||
@a.untrusted?.should be_true
|
||||
@a.delete_if{ true }
|
||||
@a.untrusted?.should be_true
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3]
|
||||
it_behaves_like :delete_if, :delete_if
|
||||
end
|
66
spec/ruby/core/array/delete_spec.rb
Normal file
66
spec/ruby/core/array/delete_spec.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#delete" do
|
||||
it "removes elements that are #== to object" do
|
||||
x = mock('delete')
|
||||
def x.==(other) 3 == other end
|
||||
|
||||
a = [1, 2, 3, x, 4, 3, 5, x]
|
||||
a.delete mock('not contained')
|
||||
a.should == [1, 2, 3, x, 4, 3, 5, x]
|
||||
|
||||
a.delete 3
|
||||
a.should == [1, 2, 4, 5]
|
||||
end
|
||||
|
||||
it "calculates equality correctly for reference values" do
|
||||
a = ["foo", "bar", "foo", "quux", "foo"]
|
||||
a.delete "foo"
|
||||
a.should == ["bar","quux"]
|
||||
end
|
||||
|
||||
it "returns object or nil if no elements match object" do
|
||||
[1, 2, 4, 5].delete(1).should == 1
|
||||
[1, 2, 4, 5].delete(3).should == nil
|
||||
end
|
||||
|
||||
it "may be given a block that is executed if no element matches object" do
|
||||
[1].delete(1) {:not_found}.should == 1
|
||||
[].delete('a') {:not_found}.should == :not_found
|
||||
end
|
||||
|
||||
it "returns nil if the array is empty due to a shift" do
|
||||
a = [1]
|
||||
a.shift
|
||||
a.delete(nil).should == nil
|
||||
end
|
||||
|
||||
it "returns nil on a frozen array if a modification does not take place" do
|
||||
[1, 2, 3].freeze.delete(0).should == nil
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { [1, 2, 3].freeze.delete(1) }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "keeps tainted status" do
|
||||
a = [1, 2]
|
||||
a.taint
|
||||
a.tainted?.should be_true
|
||||
a.delete(2)
|
||||
a.tainted?.should be_true
|
||||
a.delete(1) # now empty
|
||||
a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
a = [1, 2]
|
||||
a.untrust
|
||||
a.untrusted?.should be_true
|
||||
a.delete(2)
|
||||
a.untrusted?.should be_true
|
||||
a.delete(1) # now empty
|
||||
a.untrusted?.should be_true
|
||||
end
|
||||
end
|
54
spec/ruby/core/array/dig_spec.rb
Normal file
54
spec/ruby/core/array/dig_spec.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
ruby_version_is '2.3' do
|
||||
describe "Array#dig" do
|
||||
|
||||
it "returns #at with one arg" do
|
||||
['a'].dig(0).should == 'a'
|
||||
['a'].dig(1).should be_nil
|
||||
end
|
||||
|
||||
it "recurses array elements" do
|
||||
a = [ [ 1, [2, '3'] ] ]
|
||||
a.dig(0, 0).should == 1
|
||||
a.dig(0, 1, 1).should == '3'
|
||||
a.dig(0, -1, 0).should == 2
|
||||
end
|
||||
|
||||
it "returns the nested value specified if the sequence includes a key" do
|
||||
a = [42, { foo: :bar }]
|
||||
a.dig(1, :foo).should == :bar
|
||||
end
|
||||
|
||||
it "raises a TypeError for a non-numeric index" do
|
||||
lambda {
|
||||
['a'].dig(:first)
|
||||
}.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if any intermediate step does not respond to #dig" do
|
||||
a = [1, 2]
|
||||
lambda {
|
||||
a.dig(0, 1)
|
||||
}.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if no arguments provided" do
|
||||
lambda {
|
||||
[10].dig()
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns nil if any intermediate step is nil" do
|
||||
a = [[1, [2, 3]]]
|
||||
a.dig(1, 2, 3).should == nil
|
||||
end
|
||||
|
||||
it "calls #dig on the result of #at with the remaining arguments" do
|
||||
h = [[nil, [nil, nil, 42]]]
|
||||
h[0].should_receive(:dig).with(1, 2).and_return(42)
|
||||
h.dig(0, 1, 2).should == 42
|
||||
end
|
||||
|
||||
end
|
||||
end
|
33
spec/ruby/core/array/drop_spec.rb
Normal file
33
spec/ruby/core/array/drop_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#drop" do
|
||||
it "removes the specified number of elements from the start of the array" do
|
||||
[1, 2, 3, 4, 5].drop(2).should == [3, 4, 5]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if the number of elements specified is negative" do
|
||||
lambda { [1, 2].drop(-3) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns an empty Array if all elements are dropped" do
|
||||
[1, 2].drop(2).should == []
|
||||
end
|
||||
|
||||
it "returns an empty Array when called on an empty Array" do
|
||||
[].drop(0).should == []
|
||||
end
|
||||
|
||||
it "does not remove any elements when passed zero" do
|
||||
[1, 2].drop(0).should == [1, 2]
|
||||
end
|
||||
|
||||
it "returns an empty Array if more elements than exist are dropped" do
|
||||
[1, 2].drop(3).should == []
|
||||
end
|
||||
|
||||
it 'acts correctly after a shift' do
|
||||
ary = [nil, 1, 2]
|
||||
ary.shift
|
||||
ary.drop(1).should == [2]
|
||||
end
|
||||
end
|
15
spec/ruby/core/array/drop_while_spec.rb
Normal file
15
spec/ruby/core/array/drop_while_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#drop_while" do
|
||||
it "removes elements from the start of the array while the block evaluates to true" do
|
||||
[1, 2, 3, 4].drop_while { |n| n < 4 }.should == [4]
|
||||
end
|
||||
|
||||
it "removes elements from the start of the array until the block returns nil" do
|
||||
[1, 2, 3, nil, 5].drop_while { |n| n }.should == [nil, 5]
|
||||
end
|
||||
|
||||
it "removes elements from the start of the array until the block returns false" do
|
||||
[1, 2, 3, false, 5].drop_while { |n| n }.should == [false, 5]
|
||||
end
|
||||
end
|
31
spec/ruby/core/array/dup_spec.rb
Normal file
31
spec/ruby/core/array/dup_spec.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/clone', __FILE__)
|
||||
|
||||
describe "Array#dup" do
|
||||
it_behaves_like :array_clone, :dup # FIX: no, clone and dup are not alike
|
||||
|
||||
it "does not copy frozen status from the original" do
|
||||
a = [1, 2, 3, 4]
|
||||
b = [1, 2, 3, 4]
|
||||
a.freeze
|
||||
aa = a.dup
|
||||
bb = b.dup
|
||||
|
||||
aa.frozen?.should be_false
|
||||
bb.frozen?.should be_false
|
||||
end
|
||||
|
||||
it "does not copy singleton methods" do
|
||||
a = [1, 2, 3, 4]
|
||||
b = [1, 2, 3, 4]
|
||||
def a.a_singleton_method; end
|
||||
aa = a.dup
|
||||
bb = b.dup
|
||||
|
||||
a.respond_to?(:a_singleton_method).should be_true
|
||||
b.respond_to?(:a_singleton_method).should be_false
|
||||
aa.respond_to?(:a_singleton_method).should be_false
|
||||
bb.respond_to?(:a_singleton_method).should be_false
|
||||
end
|
||||
end
|
42
spec/ruby/core/array/each_index_spec.rb
Normal file
42
spec/ruby/core/array/each_index_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/enumeratorize', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
# Modifying a collection while the contents are being iterated
|
||||
# gives undefined behavior. See
|
||||
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
|
||||
|
||||
describe "Array#each_index" do
|
||||
before :each do
|
||||
ScratchPad.record []
|
||||
end
|
||||
|
||||
it "passes the index of each element to the block" do
|
||||
a = ['a', 'b', 'c', 'd']
|
||||
a.each_index { |i| ScratchPad << i }
|
||||
ScratchPad.recorded.should == [0, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
a = [:a, :b, :c]
|
||||
a.each_index { |i| }.should equal(a)
|
||||
end
|
||||
|
||||
it "is not confused by removing elements from the front" do
|
||||
a = [1, 2, 3]
|
||||
|
||||
a.shift
|
||||
ScratchPad.record []
|
||||
a.each_index { |i| ScratchPad << i }
|
||||
ScratchPad.recorded.should == [0, 1]
|
||||
|
||||
a.shift
|
||||
ScratchPad.record []
|
||||
a.each_index { |i| ScratchPad << i }
|
||||
ScratchPad.recorded.should == [0]
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorize, :each_index
|
||||
it_behaves_like :enumeratorized_with_origin_size, :each_index, [1,2,3]
|
||||
end
|
32
spec/ruby/core/array/each_spec.rb
Normal file
32
spec/ruby/core/array/each_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/enumeratorize', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
# Modifying a collection while the contents are being iterated
|
||||
# gives undefined behavior. See
|
||||
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
|
||||
|
||||
describe "Array#each" do
|
||||
it "yields each element to the block" do
|
||||
a = []
|
||||
x = [1, 2, 3]
|
||||
x.each { |item| a << item }.should equal(x)
|
||||
a.should == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "yields each element to a block that takes multiple arguments" do
|
||||
a = [[1, 2], :a, [3, 4]]
|
||||
b = []
|
||||
|
||||
a.each { |x, y| b << x }
|
||||
b.should == [1, :a, 3]
|
||||
|
||||
b = []
|
||||
a.each { |x, y| b << y }
|
||||
b.should == [2, nil, 4]
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorize, :each
|
||||
it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3]
|
||||
end
|
50
spec/ruby/core/array/element_reference_spec.rb
Normal file
50
spec/ruby/core/array/element_reference_spec.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/slice', __FILE__)
|
||||
|
||||
describe "Array#[]" do
|
||||
it_behaves_like(:array_slice, :[])
|
||||
end
|
||||
|
||||
describe "Array.[]" do
|
||||
it "[] should return a new array populated with the given elements" do
|
||||
array = Array[1, 'a', nil]
|
||||
array[0].should == 1
|
||||
array[1].should == 'a'
|
||||
array[2].should == nil
|
||||
end
|
||||
|
||||
it "when applied to a literal nested array, unpacks its elements into the containing array" do
|
||||
Array[1, 2, *[3, 4, 5]].should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "when applied to a nested referenced array, unpacks its elements into the containing array" do
|
||||
splatted_array = Array[3, 4, 5]
|
||||
Array[1, 2, *splatted_array].should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "can unpack 2 or more nested referenced array" do
|
||||
splatted_array = Array[3, 4, 5]
|
||||
splatted_array2 = Array[6, 7, 8]
|
||||
Array[1, 2, *splatted_array, *splatted_array2].should == [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
end
|
||||
|
||||
it "constructs a nested Hash for tailing key-value pairs" do
|
||||
Array[1, 2, 3 => 4, 5 => 6].should == [1, 2, { 3 => 4, 5 => 6 }]
|
||||
end
|
||||
|
||||
describe "with a subclass of Array" do
|
||||
before :each do
|
||||
ScratchPad.clear
|
||||
end
|
||||
|
||||
it "returns an instance of the subclass" do
|
||||
ArraySpecs::MyArray[1, 2, 3].should be_an_instance_of(ArraySpecs::MyArray)
|
||||
end
|
||||
|
||||
it "does not call #initialize on the subclass instance" do
|
||||
ArraySpecs::MyArray[1, 2, 3].should == [1, 2, 3]
|
||||
ScratchPad.recorded.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
417
spec/ruby/core/array/element_set_spec.rb
Normal file
417
spec/ruby/core/array/element_set_spec.rb
Normal file
|
@ -0,0 +1,417 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#[]=" do
|
||||
it "sets the value of the element at index" do
|
||||
a = [1, 2, 3, 4]
|
||||
a[2] = 5
|
||||
a[-1] = 6
|
||||
a[5] = 3
|
||||
a.should == [1, 2, 5, 6, nil, 3]
|
||||
|
||||
a = []
|
||||
a[4] = "e"
|
||||
a.should == [nil, nil, nil, nil, "e"]
|
||||
a[3] = "d"
|
||||
a.should == [nil, nil, nil, "d", "e"]
|
||||
a[0] = "a"
|
||||
a.should == ["a", nil, nil, "d", "e"]
|
||||
a[-3] = "C"
|
||||
a.should == ["a", nil, "C", "d", "e"]
|
||||
a[-1] = "E"
|
||||
a.should == ["a", nil, "C", "d", "E"]
|
||||
a[-5] = "A"
|
||||
a.should == ["A", nil, "C", "d", "E"]
|
||||
a[5] = "f"
|
||||
a.should == ["A", nil, "C", "d", "E", "f"]
|
||||
a[1] = []
|
||||
a.should == ["A", [], "C", "d", "E", "f"]
|
||||
a[-1] = nil
|
||||
a.should == ["A", [], "C", "d", "E", nil]
|
||||
end
|
||||
|
||||
it "sets the section defined by [start,length] to other" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a[0, 1] = 2
|
||||
a[3, 2] = ['a', 'b', 'c', 'd']
|
||||
a.should == [2, 2, 3, "a", "b", "c", "d", 6]
|
||||
end
|
||||
it "replaces the section defined by [start,length] with the given values" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a[3, 2] = 'a', 'b', 'c', 'd'
|
||||
a.should == [1, 2, 3, "a", "b", "c", "d", 6]
|
||||
end
|
||||
|
||||
it "just sets the section defined by [start,length] to other even if other is nil" do
|
||||
a = ['a', 'b', 'c', 'd', 'e']
|
||||
a[1, 3] = nil
|
||||
a.should == ["a", nil, "e"]
|
||||
end
|
||||
|
||||
it "returns nil if the rhs is nil" do
|
||||
a = [1, 2, 3]
|
||||
(a[1, 3] = nil).should == nil
|
||||
(a[1..3] = nil).should == nil
|
||||
end
|
||||
|
||||
it "sets the section defined by range to other" do
|
||||
a = [6, 5, 4, 3, 2, 1]
|
||||
a[1...2] = 9
|
||||
a[3..6] = [6, 6, 6]
|
||||
a.should == [6, 9, 4, 6, 6, 6]
|
||||
end
|
||||
|
||||
it "replaces the section defined by range with the given values" do
|
||||
a = [6, 5, 4, 3, 2, 1]
|
||||
a[3..6] = :a, :b, :c
|
||||
a.should == [6, 5, 4, :a, :b, :c]
|
||||
end
|
||||
|
||||
it "just sets the section defined by range to other even if other is nil" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[0..1] = nil
|
||||
a.should == [nil, 3, 4, 5]
|
||||
end
|
||||
|
||||
it 'expands and nil-pads the array if section assigned by range is outside array boundaries' do
|
||||
a = ['a']
|
||||
a[3..4] = ['b', 'c']
|
||||
a.should == ['a', nil, nil, 'b', 'c']
|
||||
end
|
||||
|
||||
it "calls to_int on its start and length arguments" do
|
||||
obj = mock('to_int')
|
||||
obj.stub!(:to_int).and_return(2)
|
||||
|
||||
a = [1, 2, 3, 4]
|
||||
a[obj, 0] = [9]
|
||||
a.should == [1, 2, 9, 3, 4]
|
||||
a[obj, obj] = []
|
||||
a.should == [1, 2, 4]
|
||||
a[obj] = -1
|
||||
a.should == [1, 2, -1]
|
||||
end
|
||||
|
||||
it "checks frozen before attempting to coerce arguments" do
|
||||
a = [1,2,3,4].freeze
|
||||
lambda {a[:foo] = 1}.should raise_error(RuntimeError)
|
||||
lambda {a[:foo, :bar] = 1}.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "sets elements in the range arguments when passed ranges" do
|
||||
ary = [1, 2, 3]
|
||||
rhs = [nil, [], ["x"], ["x", "y"]]
|
||||
(0 .. ary.size + 2).each do |a|
|
||||
(a .. ary.size + 3).each do |b|
|
||||
rhs.each do |c|
|
||||
ary1 = ary.dup
|
||||
ary1[a .. b] = c
|
||||
ary2 = ary.dup
|
||||
ary2[a, 1 + b-a] = c
|
||||
ary1.should == ary2
|
||||
|
||||
ary1 = ary.dup
|
||||
ary1[a ... b] = c
|
||||
ary2 = ary.dup
|
||||
ary2[a, b-a] = c
|
||||
ary1.should == ary2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "inserts the given elements with [range] which the range is zero-width" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1...1] = 0
|
||||
ary.should == [1, 0, 2, 3]
|
||||
ary[1...1] = [5]
|
||||
ary.should == [1, 5, 0, 2, 3]
|
||||
ary[1...1] = :a, :b, :c
|
||||
ary.should == [1, :a, :b, :c, 5, 0, 2, 3]
|
||||
end
|
||||
|
||||
it "inserts the given elements with [start, length] which length is zero" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1, 0] = 0
|
||||
ary.should == [1, 0, 2, 3]
|
||||
ary[1, 0] = [5]
|
||||
ary.should == [1, 5, 0, 2, 3]
|
||||
ary[1, 0] = :a, :b, :c
|
||||
ary.should == [1, :a, :b, :c, 5, 0, 2, 3]
|
||||
end
|
||||
|
||||
# Now we only have to test cases where the start, length interface would
|
||||
# have raise an exception because of negative size
|
||||
it "inserts the given elements with [range] which the range has negative width" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1..0] = 0
|
||||
ary.should == [1, 0, 2, 3]
|
||||
ary[1..0] = [4, 3]
|
||||
ary.should == [1, 4, 3, 0, 2, 3]
|
||||
ary[1..0] = :a, :b, :c
|
||||
ary.should == [1, :a, :b, :c, 4, 3, 0, 2, 3]
|
||||
end
|
||||
|
||||
it "just inserts nil if the section defined by range is zero-width and the rhs is nil" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1...1] = nil
|
||||
ary.should == [1, nil, 2, 3]
|
||||
end
|
||||
|
||||
it "just inserts nil if the section defined by range has negative width and the rhs is nil" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1..0] = nil
|
||||
ary.should == [1, nil, 2, 3]
|
||||
end
|
||||
|
||||
it "does nothing if the section defined by range is zero-width and the rhs is an empty array" do
|
||||
ary = [1, 2, 3]
|
||||
ary[1...1] = []
|
||||
ary.should == [1, 2, 3]
|
||||
end
|
||||
it "does nothing if the section defined by range has negative width and the rhs is an empty array" do
|
||||
ary = [1, 2, 3, 4, 5]
|
||||
ary[1...0] = []
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
ary[-2..2] = []
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "tries to convert Range elements to Integers using #to_int with [m..n] and [m...n]" do
|
||||
from = mock('from')
|
||||
to = mock('to')
|
||||
|
||||
# So we can construct a range out of them...
|
||||
def from.<=>(o) 0 end
|
||||
def to.<=>(o) 0 end
|
||||
|
||||
def from.to_int() 1 end
|
||||
def to.to_int() -2 end
|
||||
|
||||
a = [1, 2, 3, 4]
|
||||
|
||||
a[from .. to] = ["a", "b", "c"]
|
||||
a.should == [1, "a", "b", "c", 4]
|
||||
|
||||
a[to .. from] = ["x"]
|
||||
a.should == [1, "a", "b", "x", "c", 4]
|
||||
lambda { a["a" .. "b"] = [] }.should raise_error(TypeError)
|
||||
lambda { a[from .. "b"] = [] }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an IndexError when passed indexes out of bounds" do
|
||||
a = [1, 2, 3, 4]
|
||||
lambda { a[-5] = "" }.should raise_error(IndexError)
|
||||
lambda { a[-5, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[-5, 0] = "" }.should raise_error(IndexError)
|
||||
lambda { a[-5, 1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[-5, 2] = "" }.should raise_error(IndexError)
|
||||
lambda { a[-5, 10] = "" }.should raise_error(IndexError)
|
||||
|
||||
lambda { a[-5..-5] = "" }.should raise_error(RangeError)
|
||||
lambda { a[-5...-5] = "" }.should raise_error(RangeError)
|
||||
lambda { a[-5..-4] = "" }.should raise_error(RangeError)
|
||||
lambda { a[-5...-4] = "" }.should raise_error(RangeError)
|
||||
lambda { a[-5..10] = "" }.should raise_error(RangeError)
|
||||
lambda { a[-5...10] = "" }.should raise_error(RangeError)
|
||||
|
||||
# ok
|
||||
a[0..-9] = [1]
|
||||
a.should == [1, 1, 2, 3, 4]
|
||||
end
|
||||
|
||||
it "calls to_ary on its rhs argument for multi-element sets" do
|
||||
obj = mock('to_ary')
|
||||
def obj.to_ary() [1, 2, 3] end
|
||||
ary = [1, 2]
|
||||
ary[0, 0] = obj
|
||||
ary.should == [1, 2, 3, 1, 2]
|
||||
ary[1, 10] = obj
|
||||
ary.should == [1, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "does not call to_ary on rhs array subclasses for multi-element sets" do
|
||||
ary = []
|
||||
ary[0, 0] = ArraySpecs::ToAryArray[5, 6, 7]
|
||||
ary.should == [5, 6, 7]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array[0, 0] = [] }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#[]= with [index]" do
|
||||
it "returns value assigned if idx is inside array" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[3] = 6).should == 6
|
||||
end
|
||||
|
||||
it "returns value assigned if idx is right beyond right array boundary" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[5] = 6).should == 6
|
||||
end
|
||||
|
||||
it "returns value assigned if idx far beyond right array boundary" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[10] = 6).should == 6
|
||||
end
|
||||
|
||||
it "sets the value of the element at index" do
|
||||
a = [1, 2, 3, 4]
|
||||
a[2] = 5
|
||||
a[-1] = 6
|
||||
a[5] = 3
|
||||
a.should == [1, 2, 5, 6, nil, 3]
|
||||
end
|
||||
|
||||
it "sets the value of the element if it is right beyond the array boundary" do
|
||||
a = [1, 2, 3, 4]
|
||||
a[4] = 8
|
||||
a.should == [1, 2, 3, 4, 8]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "Array#[]= with [index, count]" do
|
||||
it "returns non-array value if non-array value assigned" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[2, 3] = 10).should == 10
|
||||
end
|
||||
|
||||
it "returns array if array assigned" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[2, 3] = [4, 5]).should == [4, 5]
|
||||
end
|
||||
|
||||
it "just sets the section defined by [start,length] to nil even if the rhs is nil" do
|
||||
a = ['a', 'b', 'c', 'd', 'e']
|
||||
a[1, 3] = nil
|
||||
a.should == ["a", nil, "e"]
|
||||
end
|
||||
|
||||
it "just sets the section defined by [start,length] to nil if negative index within bounds, cnt > 0 and the rhs is nil" do
|
||||
a = ['a', 'b', 'c', 'd', 'e']
|
||||
a[-3, 2] = nil
|
||||
a.should == ["a", "b", nil, "e"]
|
||||
end
|
||||
|
||||
it "replaces the section defined by [start,length] to other" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a[0, 1] = 2
|
||||
a[3, 2] = ['a', 'b', 'c', 'd']
|
||||
a.should == [2, 2, 3, "a", "b", "c", "d", 6]
|
||||
end
|
||||
|
||||
it "replaces the section to other if idx < 0 and cnt > 0" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a[-3, 2] = ["x", "y", "z"]
|
||||
a.should == [1, 2, 3, "x", "y", "z", 6]
|
||||
end
|
||||
|
||||
it "replaces the section to other even if cnt spanning beyond the array boundary" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[-1, 3] = [7, 8]
|
||||
a.should == [1, 2, 3, 4, 7, 8]
|
||||
end
|
||||
|
||||
it "pads the Array with nils if the span is past the end" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[10, 1] = [1]
|
||||
a.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil, 1]
|
||||
|
||||
b = [1, 2, 3, 4, 5]
|
||||
b[10, 0] = [1]
|
||||
a.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil, 1]
|
||||
end
|
||||
|
||||
it "inserts other section in place defined by idx" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[3, 0] = [7, 8]
|
||||
a.should == [1, 2, 3, 7, 8, 4, 5]
|
||||
|
||||
b = [1, 2, 3, 4, 5]
|
||||
b[1, 0] = b
|
||||
b.should == [1, 1, 2, 3, 4, 5, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "raises an IndexError when passed start and negative length" do
|
||||
a = [1, 2, 3, 4]
|
||||
lambda { a[-2, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[0, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[2, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[4, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { a[10, -1] = "" }.should raise_error(IndexError)
|
||||
lambda { [1, 2, 3, 4, 5][2, -1] = [7, 8] }.should raise_error(IndexError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#[]= with [m..n]" do
|
||||
it "returns non-array value if non-array value assigned" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[2..4] = 10).should == 10
|
||||
end
|
||||
|
||||
it "returns array if array assigned" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
(a[2..4] = [7, 8]).should == [7, 8]
|
||||
end
|
||||
|
||||
it "just sets the section defined by range to nil even if the rhs is nil" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[0..1] = nil
|
||||
a.should == [nil, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "just sets the section defined by range to nil if m and n < 0 and the rhs is nil" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[-3..-2] = nil
|
||||
a.should == [1, 2, nil, 5]
|
||||
end
|
||||
|
||||
it "replaces the section defined by range" do
|
||||
a = [6, 5, 4, 3, 2, 1]
|
||||
a[1...2] = 9
|
||||
a[3..6] = [6, 6, 6]
|
||||
a.should == [6, 9, 4, 6, 6, 6]
|
||||
end
|
||||
|
||||
it "replaces the section if m and n < 0" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[-3..-2] = [7, 8, 9]
|
||||
a.should == [1, 2, 7, 8, 9, 5]
|
||||
end
|
||||
|
||||
it "replaces the section if m < 0 and n > 0" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[-4..3] = [8]
|
||||
a.should == [1, 8, 5]
|
||||
end
|
||||
|
||||
it "inserts the other section at m if m > n" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a[3..1] = [8]
|
||||
a.should == [1, 2, 3, 8, 4, 5]
|
||||
end
|
||||
|
||||
it "accepts Range subclasses" do
|
||||
a = [1, 2, 3, 4]
|
||||
range_incl = ArraySpecs::MyRange.new(1, 2)
|
||||
range_excl = ArraySpecs::MyRange.new(-3, -1, true)
|
||||
|
||||
a[range_incl] = ["a", "b"]
|
||||
a.should == [1, "a", "b", 4]
|
||||
a[range_excl] = ["A", "B"]
|
||||
a.should == [1, "A", "B", 4]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#[] after a shift" do
|
||||
it "works for insertion" do
|
||||
a = [1,2]
|
||||
a.shift
|
||||
a.shift
|
||||
a[0,0] = [3,4]
|
||||
a.should == [3,4]
|
||||
end
|
||||
end
|
10
spec/ruby/core/array/empty_spec.rb
Normal file
10
spec/ruby/core/array/empty_spec.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#empty?" do
|
||||
it "returns true if the array has no elements" do
|
||||
[].empty?.should == true
|
||||
[1].empty?.should == false
|
||||
[1, 2].empty?.should == false
|
||||
end
|
||||
end
|
19
spec/ruby/core/array/eql_spec.rb
Normal file
19
spec/ruby/core/array/eql_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/eql', __FILE__)
|
||||
|
||||
describe "Array#eql?" do
|
||||
it_behaves_like :array_eql, :eql?
|
||||
|
||||
it "returns false if any corresponding elements are not #eql?" do
|
||||
[1, 2, 3, 4].send(@method, [1, 2, 3, 4.0]).should be_false
|
||||
end
|
||||
|
||||
it "returns false if other is not a kind of Array" do
|
||||
obj = mock("array eql?")
|
||||
obj.should_not_receive(:to_ary)
|
||||
obj.should_not_receive(@method)
|
||||
|
||||
[1, 2, 3].send(@method, obj).should be_false
|
||||
end
|
||||
end
|
51
spec/ruby/core/array/equal_value_spec.rb
Normal file
51
spec/ruby/core/array/equal_value_spec.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/eql', __FILE__)
|
||||
|
||||
describe "Array#==" do
|
||||
it_behaves_like :array_eql, :==
|
||||
|
||||
it "compares with an equivalent Array-like object using #to_ary" do
|
||||
obj = mock('array-like')
|
||||
obj.should_receive(:respond_to?).at_least(1).with(:to_ary).and_return(true)
|
||||
obj.should_receive(:==).with([1]).at_least(1).and_return(true)
|
||||
|
||||
([1] == obj).should be_true
|
||||
([[1]] == [obj]).should be_true
|
||||
([[[1], 3], 2] == [[obj, 3], 2]).should be_true
|
||||
|
||||
# recursive arrays
|
||||
arr1 = [[1]]
|
||||
arr1 << arr1
|
||||
arr2 = [obj]
|
||||
arr2 << arr2
|
||||
(arr1 == arr2).should be_true
|
||||
(arr2 == arr1).should be_true
|
||||
end
|
||||
|
||||
it "returns false if any corresponding elements are not #==" do
|
||||
a = ["a", "b", "c"]
|
||||
b = ["a", "b", "not equal value"]
|
||||
a.should_not == b
|
||||
|
||||
c = mock("c")
|
||||
c.should_receive(:==).and_return(false)
|
||||
["a", "b", c].should_not == a
|
||||
end
|
||||
|
||||
it "returns true if corresponding elements are #==" do
|
||||
[].should == []
|
||||
["a", "c", 7].should == ["a", "c", 7]
|
||||
|
||||
[1, 2, 3].should == [1.0, 2.0, 3.0]
|
||||
|
||||
obj = mock('5')
|
||||
obj.should_receive(:==).and_return(true)
|
||||
[obj].should == [5]
|
||||
end
|
||||
|
||||
# As per bug #1720
|
||||
it "returns false for [NaN] == [NaN]" do
|
||||
[nan_value].should_not == [nan_value]
|
||||
end
|
||||
end
|
55
spec/ruby/core/array/fetch_spec.rb
Normal file
55
spec/ruby/core/array/fetch_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#fetch" do
|
||||
it "returns the element at the passed index" do
|
||||
[1, 2, 3].fetch(1).should == 2
|
||||
[nil].fetch(0).should == nil
|
||||
end
|
||||
|
||||
it "counts negative indices backwards from end" do
|
||||
[1, 2, 3, 4].fetch(-1).should == 4
|
||||
end
|
||||
|
||||
it "raises an IndexError if there is no element at index" do
|
||||
lambda { [1, 2, 3].fetch(3) }.should raise_error(IndexError)
|
||||
lambda { [1, 2, 3].fetch(-4) }.should raise_error(IndexError)
|
||||
lambda { [].fetch(0) }.should raise_error(IndexError)
|
||||
end
|
||||
|
||||
it "returns default if there is no element at index if passed a default value" do
|
||||
[1, 2, 3].fetch(5, :not_found).should == :not_found
|
||||
[1, 2, 3].fetch(5, nil).should == nil
|
||||
[1, 2, 3].fetch(-4, :not_found).should == :not_found
|
||||
[nil].fetch(0, :not_found).should == nil
|
||||
end
|
||||
|
||||
it "returns the value of block if there is no element at index if passed a block" do
|
||||
[1, 2, 3].fetch(9) { |i| i * i }.should == 81
|
||||
[1, 2, 3].fetch(-9) { |i| i * i }.should == 81
|
||||
end
|
||||
|
||||
it "passes the original index argument object to the block, not the converted Integer" do
|
||||
o = mock('5')
|
||||
def o.to_int(); 5; end
|
||||
|
||||
[1, 2, 3].fetch(o) { |i| i }.should equal(o)
|
||||
end
|
||||
|
||||
it "gives precedence to the default block over the default argument" do
|
||||
lambda {
|
||||
@result = [1, 2, 3].fetch(9, :foo) { |i| i * i }
|
||||
}.should complain(/block supersedes default value argument/)
|
||||
@result.should == 81
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Integer using #to_int" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
["a", "b", "c"].fetch(obj).should == "c"
|
||||
end
|
||||
|
||||
it "raises a TypeError when the passed argument can't be coerced to Integer" do
|
||||
lambda { [].fetch("cat") }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
317
spec/ruby/core/array/fill_spec.rb
Normal file
317
spec/ruby/core/array/fill_spec.rb
Normal file
|
@ -0,0 +1,317 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#fill" do
|
||||
before :all do
|
||||
@never_passed = lambda do |i|
|
||||
raise ExpectationNotMetError, "the control path should not pass here"
|
||||
end
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
ary = [1, 2, 3]
|
||||
ary.fill(:a).should equal(ary)
|
||||
end
|
||||
|
||||
it "is destructive" do
|
||||
ary = [1, 2, 3]
|
||||
ary.fill(:a)
|
||||
ary.should == [:a, :a, :a]
|
||||
end
|
||||
|
||||
it "does not replicate the filler" do
|
||||
ary = [1, 2, 3, 4]
|
||||
str = "x"
|
||||
ary.fill(str).should == [str, str, str, str]
|
||||
str << "y"
|
||||
ary.should == [str, str, str, str]
|
||||
ary[0].should equal(str)
|
||||
ary[1].should equal(str)
|
||||
ary[2].should equal(str)
|
||||
ary[3].should equal(str)
|
||||
end
|
||||
|
||||
it "replaces all elements in the array with the filler if not given a index nor a length" do
|
||||
ary = ['a', 'b', 'c', 'duh']
|
||||
ary.fill(8).should == [8, 8, 8, 8]
|
||||
|
||||
str = "x"
|
||||
ary.fill(str).should == [str, str, str, str]
|
||||
end
|
||||
|
||||
it "replaces all elements with the value of block (index given to block)" do
|
||||
[nil, nil, nil, nil].fill { |i| i * 2 }.should == [0, 2, 4, 6]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.fill('x') }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on an empty frozen array" do
|
||||
lambda { ArraySpecs.empty_frozen_array.fill('x') }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if 4 or more arguments are passed when no block given" do
|
||||
lambda { [].fill('a') }.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [].fill('a', 1) }.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [].fill('a', 1, 2) }.should_not raise_error(ArgumentError)
|
||||
lambda { [].fill('a', 1, 2, true) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if no argument passed and no block given" do
|
||||
lambda { [].fill }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if 3 or more arguments are passed when a block given" do
|
||||
lambda { [].fill() {|i|} }.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [].fill(1) {|i|} }.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError)
|
||||
lambda { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#fill with (filler, index, length)" do
|
||||
it "replaces length elements beginning with the index with the filler if given an index and a length" do
|
||||
ary = [1, 2, 3, 4, 5, 6]
|
||||
ary.fill('x', 2, 3).should == [1, 2, 'x', 'x', 'x', 6]
|
||||
end
|
||||
|
||||
it "replaces length elements beginning with the index with the value of block" do
|
||||
[true, false, true, false, true, false, true].fill(1, 4) { |i| i + 3 }.should == [true, 4, 5, 6, 7, false, true]
|
||||
end
|
||||
|
||||
it "replaces all elements after the index if given an index and no length" do
|
||||
ary = [1, 2, 3]
|
||||
ary.fill('x', 1).should == [1, 'x', 'x']
|
||||
ary.fill(1){|i| i*2}.should == [1, 2, 4]
|
||||
end
|
||||
|
||||
it "replaces all elements after the index if given an index and nil as a length" do
|
||||
a = [1, 2, 3]
|
||||
a.fill('x', 1, nil).should == [1, 'x', 'x']
|
||||
a.fill(1, nil){|i| i*2}.should == [1, 2, 4]
|
||||
a.fill('y', nil).should == ['y', 'y', 'y']
|
||||
end
|
||||
|
||||
it "replaces the last (-n) elements if given an index n which is negative and no length" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a.fill('x', -2).should == [1, 2, 3, 'x', 'x']
|
||||
a.fill(-2){|i| i.to_s}.should == [1, 2, 3, '3', '4']
|
||||
end
|
||||
|
||||
it "replaces the last (-n) elements if given an index n which is negative and nil as a length" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a.fill('x', -2, nil).should == [1, 2, 3, 'x', 'x']
|
||||
a.fill(-2, nil){|i| i.to_s}.should == [1, 2, 3, '3', '4']
|
||||
end
|
||||
|
||||
it "makes no modifications if given an index greater than end and no length" do
|
||||
[1, 2, 3, 4, 5].fill('a', 5).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(5, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "makes no modifications if given an index greater than end and nil as a length" do
|
||||
[1, 2, 3, 4, 5].fill('a', 5, nil).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(5, nil, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "replaces length elements beginning with start index if given an index >= 0 and a length >= 0" do
|
||||
[1, 2, 3, 4, 5].fill('a', 2, 0).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill('a', 2, 2).should == [1, 2, "a", "a", 5]
|
||||
|
||||
[1, 2, 3, 4, 5].fill(2, 0, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(2, 2){|i| i*2}.should == [1, 2, 4, 6, 5]
|
||||
end
|
||||
|
||||
it "increases the Array size when necessary" do
|
||||
a = [1, 2, 3]
|
||||
a.size.should == 3
|
||||
a.fill 'a', 0, 10
|
||||
a.size.should == 10
|
||||
end
|
||||
|
||||
it "pads between the last element and the index with nil if given an index which is greater than size of the array" do
|
||||
[1, 2, 3, 4, 5].fill('a', 8, 5).should == [1, 2, 3, 4, 5, nil, nil, nil, 'a', 'a', 'a', 'a', 'a']
|
||||
[1, 2, 3, 4, 5].fill(8, 5){|i| 'a'}.should == [1, 2, 3, 4, 5, nil, nil, nil, 'a', 'a', 'a', 'a', 'a']
|
||||
end
|
||||
|
||||
it "replaces length elements beginning with the (-n)th if given an index n < 0 and a length > 0" do
|
||||
[1, 2, 3, 4, 5].fill('a', -2, 2).should == [1, 2, 3, "a", "a"]
|
||||
[1, 2, 3, 4, 5].fill('a', -2, 4).should == [1, 2, 3, "a", "a", "a", "a"]
|
||||
|
||||
[1, 2, 3, 4, 5].fill(-2, 2){|i| 'a'}.should == [1, 2, 3, "a", "a"]
|
||||
[1, 2, 3, 4, 5].fill(-2, 4){|i| 'a'}.should == [1, 2, 3, "a", "a", "a", "a"]
|
||||
end
|
||||
|
||||
it "starts at 0 if the negative index is before the start of the array" do
|
||||
[1, 2, 3, 4, 5].fill('a', -25, 3).should == ['a', 'a', 'a', 4, 5]
|
||||
[1, 2, 3, 4, 5].fill('a', -10, 10).should == %w|a a a a a a a a a a|
|
||||
|
||||
[1, 2, 3, 4, 5].fill(-25, 3){|i| 'a'}.should == ['a', 'a', 'a', 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(-10, 10){|i| 'a'}.should == %w|a a a a a a a a a a|
|
||||
end
|
||||
|
||||
it "makes no modifications if the given length <= 0" do
|
||||
[1, 2, 3, 4, 5].fill('a', 2, 0).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill('a', -2, 0).should == [1, 2, 3, 4, 5]
|
||||
|
||||
[1, 2, 3, 4, 5].fill('a', 2, -2).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill('a', -2, -2).should == [1, 2, 3, 4, 5]
|
||||
|
||||
[1, 2, 3, 4, 5].fill(2, 0, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(-2, 0, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
|
||||
[1, 2, 3, 4, 5].fill(2, -2, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
[1, 2, 3, 4, 5].fill(-2, -2, &@never_passed).should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
# See: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17481
|
||||
it "does not raise an exception if the given length is negative and its absolute value does not exceed the index" do
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -1)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -2)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -3)}.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [1, 2, 3, 4].fill(3, -1, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill(3, -2, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill(3, -3, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "does not raise an exception even if the given length is negative and its absolute value exceeds the index" do
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -4)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -5)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill('a', 3, -10000)}.should_not raise_error(ArgumentError)
|
||||
|
||||
lambda { [1, 2, 3, 4].fill(3, -4, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill(3, -5, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
lambda { [1, 2, 3, 4].fill(3, -10000, &@never_passed)}.should_not raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "tries to convert the second and third arguments to Integers using #to_int" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2, 2)
|
||||
filler = mock('filler')
|
||||
filler.should_not_receive(:to_int)
|
||||
[1, 2, 3, 4, 5].fill(filler, obj, obj).should == [1, 2, filler, filler, 5]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the index is not numeric" do
|
||||
lambda { [].fill 'a', true }.should raise_error(TypeError)
|
||||
|
||||
obj = mock('nonnumeric')
|
||||
lambda { [].fill('a', obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
not_supported_on :opal do
|
||||
it "raises an ArgumentError or RangeError for too-large sizes" do
|
||||
arr = [1, 2, 3]
|
||||
lambda { arr.fill(10, 1, fixnum_max) }.should raise_error(ArgumentError)
|
||||
lambda { arr.fill(10, 1, bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#fill with (filler, range)" do
|
||||
it "replaces elements in range with object" do
|
||||
[1, 2, 3, 4, 5, 6].fill(8, 0..3).should == [8, 8, 8, 8, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(8, 0...3).should == [8, 8, 8, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 4..6).should == [1, 2, 3, 4, 'x', 'x', 'x']
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 4...6).should == [1, 2, 3, 4, 'x', 'x']
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2..-1).should == [1, 2, 3, 4, 'x', 'x']
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2...-1).should == [1, 2, 3, 4, 'x', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2...-2).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2..-2).should == [1, 2, 3, 4, 'x', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2..0).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 0...0).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 1..1).should == [1, 'x', 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
it "replaces all elements in range with the value of block" do
|
||||
[1, 1, 1, 1, 1, 1].fill(1..6) { |i| i + 1 }.should == [1, 2, 3, 4, 5, 6, 7]
|
||||
end
|
||||
|
||||
it "increases the Array size when necessary" do
|
||||
[1, 2, 3].fill('x', 1..6).should == [1, 'x', 'x', 'x', 'x', 'x', 'x']
|
||||
[1, 2, 3].fill(1..6){|i| i+1}.should == [1, 2, 3, 4, 5, 6, 7]
|
||||
end
|
||||
|
||||
it "raises a TypeError with range and length argument" do
|
||||
lambda { [].fill('x', 0 .. 2, 5) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "replaces elements between the (-m)th to the last and the (n+1)th from the first if given an range m..n where m < 0 and n >= 0" do
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4..4).should == [1, 2, 'x', 'x', 'x', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4...4).should == [1, 2, 'x', 'x', 5, 6]
|
||||
|
||||
[1, 2, 3, 4, 5, 6].fill(-4..4){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-4...4){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6]
|
||||
end
|
||||
|
||||
it "replaces elements between the (-m)th and (-n)th to the last if given an range m..n where m < 0 and n < 0" do
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4..-2).should == [1, 2, 'x', 'x', 'x', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4...-2).should == [1, 2, 'x', 'x', 5, 6]
|
||||
|
||||
[1, 2, 3, 4, 5, 6].fill(-4..-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-4...-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6]
|
||||
end
|
||||
|
||||
it "replaces elements between the (m+1)th from the first and (-n)th to the last if given an range m..n where m >= 0 and n < 0" do
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2..-2).should == [1, 2, 'x', 'x', 'x', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2...-2).should == [1, 2, 'x', 'x', 5, 6]
|
||||
|
||||
[1, 2, 3, 4, 5, 6].fill(2..-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(2...-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6]
|
||||
end
|
||||
|
||||
it "makes no modifications if given an range which implies a section of zero width" do
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2...2).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4...2).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4...-4).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2...-4).should == [1, 2, 3, 4, 5, 6]
|
||||
|
||||
[1, 2, 3, 4, 5, 6].fill(2...2, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-4...2, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-4...-4, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(2...-4, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
it "makes no modifications if given an range which implies a section of negative width" do
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2..1).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -4..1).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', -2..-4).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill('x', 2..-5).should == [1, 2, 3, 4, 5, 6]
|
||||
|
||||
[1, 2, 3, 4, 5, 6].fill(2..1, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-4..1, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(-2..-4, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
[1, 2, 3, 4, 5, 6].fill(2..-5, &@never_passed).should == [1, 2, 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
it "raises an exception if some of the given range lies before the first of the array" do
|
||||
lambda { [1, 2, 3].fill('x', -5..-3) }.should raise_error(RangeError)
|
||||
lambda { [1, 2, 3].fill('x', -5...-3) }.should raise_error(RangeError)
|
||||
lambda { [1, 2, 3].fill('x', -5..-4) }.should raise_error(RangeError)
|
||||
|
||||
lambda { [1, 2, 3].fill(-5..-3, &@never_passed) }.should raise_error(RangeError)
|
||||
lambda { [1, 2, 3].fill(-5...-3, &@never_passed) }.should raise_error(RangeError)
|
||||
lambda { [1, 2, 3].fill(-5..-4, &@never_passed) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "tries to convert the start and end of the passed range to Integers using #to_int" do
|
||||
obj = mock('to_int')
|
||||
def obj.<=>(rhs); rhs == self ? 0 : nil end
|
||||
obj.should_receive(:to_int).twice.and_return(2)
|
||||
filler = mock('filler')
|
||||
filler.should_not_receive(:to_int)
|
||||
[1, 2, 3, 4, 5].fill(filler, obj..obj).should == [1, 2, filler, 4, 5]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the start or end of the passed range is not numeric" do
|
||||
obj = mock('nonnumeric')
|
||||
def obj.<=>(rhs); rhs == self ? 0 : nil end
|
||||
lambda { [].fill('a', obj..obj) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
6
spec/ruby/core/array/find_index_spec.rb
Normal file
6
spec/ruby/core/array/find_index_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/index', __FILE__)
|
||||
|
||||
describe "Array#find_index" do
|
||||
it_behaves_like :array_index, :find_index
|
||||
end
|
93
spec/ruby/core/array/first_spec.rb
Normal file
93
spec/ruby/core/array/first_spec.rb
Normal file
|
@ -0,0 +1,93 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#first" do
|
||||
it "returns the first element" do
|
||||
%w{a b c}.first.should == 'a'
|
||||
[nil].first.should == nil
|
||||
end
|
||||
|
||||
it "returns nil if self is empty" do
|
||||
[].first.should == nil
|
||||
end
|
||||
|
||||
it "returns the first count elements if given a count" do
|
||||
[true, false, true, nil, false].first(2).should == [true, false]
|
||||
end
|
||||
|
||||
it "returns an empty array when passed count on an empty array" do
|
||||
[].first(0).should == []
|
||||
[].first(1).should == []
|
||||
[].first(2).should == []
|
||||
end
|
||||
|
||||
it "returns an empty array when passed count == 0" do
|
||||
[1, 2, 3, 4, 5].first(0).should == []
|
||||
end
|
||||
|
||||
it "returns an array containing the first element when passed count == 1" do
|
||||
[1, 2, 3, 4, 5].first(1).should == [1]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when count is negative" do
|
||||
lambda { [1, 2].first(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises a RangeError when count is a Bignum" do
|
||||
lambda { [].first(bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "returns the entire array when count > length" do
|
||||
[1, 2, 3, 4, 5, 9].first(10).should == [1, 2, 3, 4, 5, 9]
|
||||
end
|
||||
|
||||
it "returns an array which is independent to the original when passed count" do
|
||||
ary = [1, 2, 3, 4, 5]
|
||||
ary.first(0).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
ary.first(1).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
ary.first(6).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.first.should equal(empty)
|
||||
|
||||
ary = ArraySpecs.head_recursive_array
|
||||
ary.first.should equal(ary)
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Integer using #to_int" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
[1, 2, 3, 4, 5].first(obj).should == [1, 2]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the passed argument is not numeric" do
|
||||
lambda { [1,2].first(nil) }.should raise_error(TypeError)
|
||||
lambda { [1,2].first("a") }.should raise_error(TypeError)
|
||||
|
||||
obj = mock("nonnumeric")
|
||||
lambda { [1,2].first(obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not return subclass instance when passed count on Array subclasses" do
|
||||
ArraySpecs::MyArray[].first(0).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[].first(2).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].first(0).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].first(1).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].first(2).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "is not destructive" do
|
||||
a = [1, 2, 3]
|
||||
a.first
|
||||
a.should == [1, 2, 3]
|
||||
a.first(2)
|
||||
a.should == [1, 2, 3]
|
||||
a.first(3)
|
||||
a.should == [1, 2, 3]
|
||||
end
|
||||
end
|
525
spec/ruby/core/array/fixtures/classes.rb
Normal file
525
spec/ruby/core/array/fixtures/classes.rb
Normal file
|
@ -0,0 +1,525 @@
|
|||
class Object
|
||||
# This helper is defined here rather than in MSpec because
|
||||
# it is only used in #pack specs.
|
||||
def pack_format(count=nil, repeat=nil)
|
||||
format = "#{instance_variable_get(:@method)}#{count}"
|
||||
format *= repeat if repeat
|
||||
format
|
||||
end
|
||||
end
|
||||
|
||||
module ArraySpecs
|
||||
SampleRange = 0..1000
|
||||
SampleCount = 1000
|
||||
|
||||
def self.frozen_array
|
||||
frozen_array = [1,2,3]
|
||||
frozen_array.freeze
|
||||
frozen_array
|
||||
end
|
||||
|
||||
def self.empty_frozen_array
|
||||
frozen_array = []
|
||||
frozen_array.freeze
|
||||
frozen_array
|
||||
end
|
||||
|
||||
def self.recursive_array
|
||||
a = [1, 'two', 3.0]
|
||||
5.times { a << a }
|
||||
a
|
||||
end
|
||||
|
||||
def self.head_recursive_array
|
||||
a = []
|
||||
5.times { a << a }
|
||||
a << 1 << 'two' << 3.0
|
||||
a
|
||||
end
|
||||
|
||||
def self.empty_recursive_array
|
||||
a = []
|
||||
a << a
|
||||
a
|
||||
end
|
||||
|
||||
class MyArray < Array
|
||||
# The #initialize method has a different signature than Array to help
|
||||
# catch places in the specs that do not assert the #initialize is not
|
||||
# called when Array methods make new instances.
|
||||
def initialize(a, b)
|
||||
self << a << b
|
||||
ScratchPad.record :my_array_initialize
|
||||
end
|
||||
end
|
||||
|
||||
class Sexp < Array
|
||||
def initialize(*args)
|
||||
super(args)
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: replace specs that use this with #should_not_receive(:to_ary)
|
||||
# expectations on regular objects (e.g. Array instances).
|
||||
class ToAryArray < Array
|
||||
def to_ary() ["to_ary", "was", "called!"] end
|
||||
end
|
||||
|
||||
class MyRange < Range; end
|
||||
|
||||
class AssocKey
|
||||
def ==(other); other == 'it'; end
|
||||
end
|
||||
|
||||
class D
|
||||
def <=>(obj)
|
||||
return 4 <=> obj unless obj.class == D
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
class SubArray < Array
|
||||
def initialize(*args)
|
||||
ScratchPad.record args
|
||||
end
|
||||
end
|
||||
|
||||
class ArrayConvertable
|
||||
attr_accessor :called
|
||||
def initialize(*values, &block)
|
||||
@values = values;
|
||||
end
|
||||
|
||||
def to_a
|
||||
self.called = :to_a
|
||||
@values
|
||||
end
|
||||
|
||||
def to_ary
|
||||
self.called = :to_ary
|
||||
@values
|
||||
end
|
||||
end
|
||||
|
||||
class SortSame
|
||||
def <=>(other); 0; end
|
||||
def ==(other); true; end
|
||||
end
|
||||
|
||||
class UFOSceptic
|
||||
def <=>(other); raise "N-uh, UFO:s do not exist!"; end
|
||||
end
|
||||
|
||||
class MockForCompared
|
||||
@@count = 0
|
||||
@@compared = false
|
||||
def initialize
|
||||
@@compared = false
|
||||
@order = (@@count += 1)
|
||||
end
|
||||
def <=>(rhs)
|
||||
@@compared = true
|
||||
return rhs.order <=> self.order
|
||||
end
|
||||
def self.compared?
|
||||
@@compared
|
||||
end
|
||||
|
||||
protected
|
||||
attr_accessor :order
|
||||
end
|
||||
|
||||
class ComparableWithFixnum
|
||||
include Comparable
|
||||
def initialize(num)
|
||||
@num = num
|
||||
end
|
||||
|
||||
def <=>(fixnum)
|
||||
@num <=> fixnum
|
||||
end
|
||||
end
|
||||
|
||||
class Uncomparable
|
||||
def <=>(obj)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.universal_pack_object
|
||||
obj = mock("string float int")
|
||||
obj.stub!(:to_int).and_return(1)
|
||||
obj.stub!(:to_str).and_return("1")
|
||||
obj.stub!(:to_f).and_return(1.0)
|
||||
obj
|
||||
end
|
||||
|
||||
LargeArray = ["test_create_table_with_force_true_does_not_drop_nonexisting_table",
|
||||
"test_add_table",
|
||||
"assert_difference",
|
||||
"assert_operator",
|
||||
"instance_variables",
|
||||
"class",
|
||||
"instance_variable_get",
|
||||
"__class__",
|
||||
"expects",
|
||||
"assert_no_difference",
|
||||
"name",
|
||||
"assert_blank",
|
||||
"assert_not_same",
|
||||
"is_a?",
|
||||
"test_add_table_with_decimals",
|
||||
"test_create_table_with_timestamps_should_create_datetime_columns",
|
||||
"assert_present",
|
||||
"assert_no_match",
|
||||
"__instance_of__",
|
||||
"assert_deprecated",
|
||||
"assert",
|
||||
"assert_throws",
|
||||
"kind_of?",
|
||||
"try",
|
||||
"__instance_variable_get__",
|
||||
"object_id",
|
||||
"timeout",
|
||||
"instance_variable_set",
|
||||
"assert_nothing_thrown",
|
||||
"__instance_variable_set__",
|
||||
"copy_object",
|
||||
"test_create_table_with_timestamps_should_create_datetime_columns_with_options",
|
||||
"assert_not_deprecated",
|
||||
"assert_in_delta",
|
||||
"id",
|
||||
"copy_metaclass",
|
||||
"test_create_table_without_a_block",
|
||||
"dup",
|
||||
"assert_not_nil",
|
||||
"send",
|
||||
"__instance_variables__",
|
||||
"to_sql",
|
||||
"mock",
|
||||
"assert_send",
|
||||
"instance_variable_defined?",
|
||||
"clone",
|
||||
"require",
|
||||
"test_migrator",
|
||||
"__instance_variable_defined_eh__",
|
||||
"frozen?",
|
||||
"test_add_column_not_null_with_default",
|
||||
"freeze",
|
||||
"test_migrator_one_up",
|
||||
"test_migrator_one_down",
|
||||
"singleton_methods",
|
||||
"method_exists?",
|
||||
"create_fixtures",
|
||||
"test_migrator_one_up_one_down",
|
||||
"test_native_decimal_insert_manual_vs_automatic",
|
||||
"instance_exec",
|
||||
"__is_a__",
|
||||
"test_migrator_double_up",
|
||||
"stub",
|
||||
"private_methods",
|
||||
"stubs",
|
||||
"test_migrator_double_down",
|
||||
"fixture_path",
|
||||
"private_singleton_methods",
|
||||
"stub_everything",
|
||||
"test_migrator_one_up_with_exception_and_rollback",
|
||||
"sequence",
|
||||
"protected_methods",
|
||||
"enum_for",
|
||||
"test_finds_migrations",
|
||||
"run_before_mocha",
|
||||
"states",
|
||||
"protected_singleton_methods",
|
||||
"to_json",
|
||||
"instance_values",
|
||||
"==",
|
||||
"mocha_setup",
|
||||
"public_methods",
|
||||
"test_finds_pending_migrations",
|
||||
"mocha_verify",
|
||||
"assert_kind_of",
|
||||
"===",
|
||||
"=~",
|
||||
"test_relative_migrations",
|
||||
"mocha_teardown",
|
||||
"gem",
|
||||
"mocha",
|
||||
"test_only_loads_pending_migrations",
|
||||
"test_add_column_with_precision_and_scale",
|
||||
"require_or_load",
|
||||
"eql?",
|
||||
"require_dependency",
|
||||
"test_native_types",
|
||||
"test_target_version_zero_should_run_only_once",
|
||||
"extend",
|
||||
"to_matcher",
|
||||
"unloadable",
|
||||
"require_association",
|
||||
"hash",
|
||||
"__id__",
|
||||
"load_dependency",
|
||||
"equals",
|
||||
"test_migrator_db_has_no_schema_migrations_table",
|
||||
"test_migrator_verbosity",
|
||||
"kind_of",
|
||||
"to_yaml",
|
||||
"to_bool",
|
||||
"test_migrator_verbosity_off",
|
||||
"taint",
|
||||
"test_migrator_going_down_due_to_version_target",
|
||||
"tainted?",
|
||||
"mocha_inspect",
|
||||
"test_migrator_rollback",
|
||||
"vim",
|
||||
"untaint",
|
||||
"taguri=",
|
||||
"test_migrator_forward",
|
||||
"test_schema_migrations_table_name",
|
||||
"test_proper_table_name",
|
||||
"all_of",
|
||||
"test_add_drop_table_with_prefix_and_suffix",
|
||||
"_setup_callbacks",
|
||||
"setup",
|
||||
"Not",
|
||||
"test_create_table_with_binary_column",
|
||||
"assert_not_equal",
|
||||
"enable_warnings",
|
||||
"acts_like?",
|
||||
"Rational",
|
||||
"_removed_setup_callbacks",
|
||||
"Table",
|
||||
"bind",
|
||||
"any_of",
|
||||
"__method__",
|
||||
"test_migrator_with_duplicates",
|
||||
"_teardown_callbacks",
|
||||
"method",
|
||||
"test_migrator_with_duplicate_names",
|
||||
"_removed_teardown_callbacks",
|
||||
"any_parameters",
|
||||
"test_migrator_with_missing_version_numbers",
|
||||
"test_add_remove_single_field_using_string_arguments",
|
||||
"test_create_table_with_custom_sequence_name",
|
||||
"test_add_remove_single_field_using_symbol_arguments",
|
||||
"_one_time_conditions_valid_14?",
|
||||
"_one_time_conditions_valid_16?",
|
||||
"run_callbacks",
|
||||
"anything",
|
||||
"silence_warnings",
|
||||
"instance_variable_names",
|
||||
"_fixture_path",
|
||||
"copy_instance_variables_from",
|
||||
"fixture_path?",
|
||||
"has_entry",
|
||||
"__marshal__",
|
||||
"_fixture_table_names",
|
||||
"__kind_of__",
|
||||
"fixture_table_names?",
|
||||
"test_add_rename",
|
||||
"assert_equal",
|
||||
"_fixture_class_names",
|
||||
"fixture_class_names?",
|
||||
"has_entries",
|
||||
"_use_transactional_fixtures",
|
||||
"people",
|
||||
"test_rename_column_using_symbol_arguments",
|
||||
"use_transactional_fixtures?",
|
||||
"instance_eval",
|
||||
"blank?",
|
||||
"with_warnings",
|
||||
"__nil__",
|
||||
"load",
|
||||
"metaclass",
|
||||
"_use_instantiated_fixtures",
|
||||
"has_key",
|
||||
"class_eval",
|
||||
"present?",
|
||||
"test_rename_column",
|
||||
"teardown",
|
||||
"use_instantiated_fixtures?",
|
||||
"method_name",
|
||||
"silence_stderr",
|
||||
"presence",
|
||||
"test_rename_column_preserves_default_value_not_null",
|
||||
"silence_stream",
|
||||
"_pre_loaded_fixtures",
|
||||
"__metaclass__",
|
||||
"__fixnum__",
|
||||
"pre_loaded_fixtures?",
|
||||
"has_value",
|
||||
"suppress",
|
||||
"to_yaml_properties",
|
||||
"test_rename_nonexistent_column",
|
||||
"test_add_index",
|
||||
"includes",
|
||||
"find_correlate_in",
|
||||
"equality_predicate_sql",
|
||||
"assert_nothing_raised",
|
||||
"let",
|
||||
"not_predicate_sql",
|
||||
"test_rename_column_with_sql_reserved_word",
|
||||
"singleton_class",
|
||||
"test_rename_column_with_an_index",
|
||||
"display",
|
||||
"taguri",
|
||||
"to_yaml_style",
|
||||
"test_remove_column_with_index",
|
||||
"size",
|
||||
"current_adapter?",
|
||||
"test_remove_column_with_multi_column_index",
|
||||
"respond_to?",
|
||||
"test_change_type_of_not_null_column",
|
||||
"is_a",
|
||||
"to_a",
|
||||
"test_rename_table_for_sqlite_should_work_with_reserved_words",
|
||||
"require_library_or_gem",
|
||||
"setup_fixtures",
|
||||
"equal?",
|
||||
"teardown_fixtures",
|
||||
"nil?",
|
||||
"fixture_table_names",
|
||||
"fixture_class_names",
|
||||
"test_create_table_without_id",
|
||||
"use_transactional_fixtures",
|
||||
"test_add_column_with_primary_key_attribute",
|
||||
"repair_validations",
|
||||
"use_instantiated_fixtures",
|
||||
"instance_of?",
|
||||
"test_create_table_adds_id",
|
||||
"test_rename_table",
|
||||
"pre_loaded_fixtures",
|
||||
"to_enum",
|
||||
"test_create_table_with_not_null_column",
|
||||
"instance_of",
|
||||
"test_change_column_nullability",
|
||||
"optionally",
|
||||
"test_rename_table_with_an_index",
|
||||
"run",
|
||||
"test_change_column",
|
||||
"default_test",
|
||||
"assert_raise",
|
||||
"test_create_table_with_defaults",
|
||||
"assert_nil",
|
||||
"flunk",
|
||||
"regexp_matches",
|
||||
"duplicable?",
|
||||
"reset_mocha",
|
||||
"stubba_method",
|
||||
"filter_backtrace",
|
||||
"test_create_table_with_limits",
|
||||
"responds_with",
|
||||
"stubba_object",
|
||||
"test_change_column_with_nil_default",
|
||||
"assert_block",
|
||||
"__show__",
|
||||
"assert_date_from_db",
|
||||
"__respond_to_eh__",
|
||||
"run_in_transaction?",
|
||||
"inspect",
|
||||
"assert_sql",
|
||||
"test_change_column_with_new_default",
|
||||
"yaml_equivalent",
|
||||
"build_message",
|
||||
"to_s",
|
||||
"test_change_column_default",
|
||||
"assert_queries",
|
||||
"pending",
|
||||
"as_json",
|
||||
"assert_no_queries",
|
||||
"test_change_column_quotes_column_names",
|
||||
"assert_match",
|
||||
"test_keeping_default_and_notnull_constaint_on_change",
|
||||
"methods",
|
||||
"connection_allow_concurrency_setup",
|
||||
"connection_allow_concurrency_teardown",
|
||||
"test_create_table_with_primary_key_prefix_as_table_name_with_underscore",
|
||||
"__send__",
|
||||
"make_connection",
|
||||
"assert_raises",
|
||||
"tap",
|
||||
"with_kcode",
|
||||
"assert_instance_of",
|
||||
"test_create_table_with_primary_key_prefix_as_table_name",
|
||||
"assert_respond_to",
|
||||
"test_change_column_default_to_null",
|
||||
"assert_same",
|
||||
"__extend__"]
|
||||
|
||||
LargeTestArraySorted = ["test_add_column_not_null_with_default",
|
||||
"test_add_column_with_precision_and_scale",
|
||||
"test_add_column_with_primary_key_attribute",
|
||||
"test_add_drop_table_with_prefix_and_suffix",
|
||||
"test_add_index",
|
||||
"test_add_remove_single_field_using_string_arguments",
|
||||
"test_add_remove_single_field_using_symbol_arguments",
|
||||
"test_add_rename",
|
||||
"test_add_table",
|
||||
"test_add_table_with_decimals",
|
||||
"test_change_column",
|
||||
"test_change_column_default",
|
||||
"test_change_column_default_to_null",
|
||||
"test_change_column_nullability",
|
||||
"test_change_column_quotes_column_names",
|
||||
"test_change_column_with_new_default",
|
||||
"test_change_column_with_nil_default",
|
||||
"test_change_type_of_not_null_column",
|
||||
"test_create_table_adds_id",
|
||||
"test_create_table_with_binary_column",
|
||||
"test_create_table_with_custom_sequence_name",
|
||||
"test_create_table_with_defaults",
|
||||
"test_create_table_with_force_true_does_not_drop_nonexisting_table",
|
||||
"test_create_table_with_limits",
|
||||
"test_create_table_with_not_null_column",
|
||||
"test_create_table_with_primary_key_prefix_as_table_name",
|
||||
"test_create_table_with_primary_key_prefix_as_table_name_with_underscore",
|
||||
"test_create_table_with_timestamps_should_create_datetime_columns",
|
||||
"test_create_table_with_timestamps_should_create_datetime_columns_with_options",
|
||||
"test_create_table_without_a_block",
|
||||
"test_create_table_without_id",
|
||||
"test_finds_migrations",
|
||||
"test_finds_pending_migrations",
|
||||
"test_keeping_default_and_notnull_constaint_on_change",
|
||||
"test_migrator",
|
||||
"test_migrator_db_has_no_schema_migrations_table",
|
||||
"test_migrator_double_down",
|
||||
"test_migrator_double_up",
|
||||
"test_migrator_forward",
|
||||
"test_migrator_going_down_due_to_version_target",
|
||||
"test_migrator_one_down",
|
||||
"test_migrator_one_up",
|
||||
"test_migrator_one_up_one_down",
|
||||
"test_migrator_one_up_with_exception_and_rollback",
|
||||
"test_migrator_rollback",
|
||||
"test_migrator_verbosity",
|
||||
"test_migrator_verbosity_off",
|
||||
"test_migrator_with_duplicate_names",
|
||||
"test_migrator_with_duplicates",
|
||||
"test_migrator_with_missing_version_numbers",
|
||||
"test_native_decimal_insert_manual_vs_automatic",
|
||||
"test_native_types",
|
||||
"test_only_loads_pending_migrations",
|
||||
"test_proper_table_name",
|
||||
"test_relative_migrations",
|
||||
"test_remove_column_with_index",
|
||||
"test_remove_column_with_multi_column_index",
|
||||
"test_rename_column",
|
||||
"test_rename_column_preserves_default_value_not_null",
|
||||
"test_rename_column_using_symbol_arguments",
|
||||
"test_rename_column_with_an_index",
|
||||
"test_rename_column_with_sql_reserved_word",
|
||||
"test_rename_nonexistent_column",
|
||||
"test_rename_table",
|
||||
"test_rename_table_for_sqlite_should_work_with_reserved_words",
|
||||
"test_rename_table_with_an_index",
|
||||
"test_schema_migrations_table_name",
|
||||
"test_target_version_zero_should_run_only_once"]
|
||||
|
||||
class PrivateToAry
|
||||
private
|
||||
|
||||
def to_ary
|
||||
[1, 2, 3]
|
||||
end
|
||||
end
|
||||
end
|
69
spec/ruby/core/array/fixtures/encoded_strings.rb
Normal file
69
spec/ruby/core/array/fixtures/encoded_strings.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
# encoding: utf-8
|
||||
module ArraySpecs
|
||||
def self.array_with_usascii_and_7bit_utf8_strings
|
||||
[
|
||||
'foo'.force_encoding('US-ASCII'),
|
||||
'bar'
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_usascii_and_utf8_strings
|
||||
[
|
||||
'foo'.force_encoding('US-ASCII'),
|
||||
'báz'
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_7bit_utf8_and_usascii_strings
|
||||
[
|
||||
'bar',
|
||||
'foo'.force_encoding('US-ASCII')
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_utf8_and_usascii_strings
|
||||
[
|
||||
'báz',
|
||||
'bar',
|
||||
'foo'.force_encoding('US-ASCII')
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_usascii_and_utf8_strings
|
||||
[
|
||||
'foo'.force_encoding('US-ASCII'),
|
||||
'bar',
|
||||
'báz'
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_utf8_and_7bit_ascii8bit_strings
|
||||
[
|
||||
'bar',
|
||||
'báz',
|
||||
'foo'.force_encoding('ASCII-8BIT')
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_utf8_and_ascii8bit_strings
|
||||
[
|
||||
'bar',
|
||||
'báz',
|
||||
[255].pack('C').force_encoding('ASCII-8BIT')
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_usascii_and_7bit_ascii8bit_strings
|
||||
[
|
||||
'bar'.force_encoding('US-ASCII'),
|
||||
'foo'.force_encoding('ASCII-8BIT')
|
||||
]
|
||||
end
|
||||
|
||||
def self.array_with_usascii_and_ascii8bit_strings
|
||||
[
|
||||
'bar'.force_encoding('US-ASCII'),
|
||||
[255].pack('C').force_encoding('ASCII-8BIT')
|
||||
]
|
||||
end
|
||||
end
|
270
spec/ruby/core/array/flatten_spec.rb
Normal file
270
spec/ruby/core/array/flatten_spec.rb
Normal file
|
@ -0,0 +1,270 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#flatten" do
|
||||
it "returns a one-dimensional flattening recursively" do
|
||||
[[[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]
|
||||
end
|
||||
|
||||
it "takes an optional argument that determines the level of recursion" do
|
||||
[ 1, 2, [3, [4, 5] ] ].flatten(1).should == [1, 2, 3, [4, 5]]
|
||||
end
|
||||
|
||||
it "returns dup when the level of recursion is 0" do
|
||||
a = [ 1, 2, [3, [4, 5] ] ]
|
||||
a.flatten(0).should == a
|
||||
a.flatten(0).should_not equal(a)
|
||||
end
|
||||
|
||||
it "ignores negative levels" do
|
||||
[ 1, 2, [ 3, 4, [5, 6] ] ].flatten(-1).should == [1, 2, 3, 4, 5, 6]
|
||||
[ 1, 2, [ 3, 4, [5, 6] ] ].flatten(-10).should == [1, 2, 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
it "tries to convert passed Objects to Integers using #to_int" do
|
||||
obj = mock("Converted to Integer")
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
|
||||
[ 1, 2, [3, [4, 5] ] ].flatten(obj).should == [1, 2, 3, [4, 5]]
|
||||
end
|
||||
|
||||
it "raises a TypeError when the passed Object can't be converted to an Integer" do
|
||||
obj = mock("Not converted")
|
||||
lambda { [ 1, 2, [3, [4, 5] ] ].flatten(obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not call flatten on elements" do
|
||||
obj = mock('[1,2]')
|
||||
obj.should_not_receive(:flatten)
|
||||
[obj, obj].flatten.should == [obj, obj]
|
||||
|
||||
obj = [5, 4]
|
||||
obj.should_not_receive(:flatten)
|
||||
[obj, obj].flatten.should == [5, 4, 5, 4]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError on recursive arrays" do
|
||||
x = []
|
||||
x << x
|
||||
lambda { x.flatten }.should raise_error(ArgumentError)
|
||||
|
||||
x = []
|
||||
y = []
|
||||
x << y
|
||||
y << x
|
||||
lambda { x.flatten }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "flattens any element which responds to #to_ary, using the return value of said method" do
|
||||
x = mock("[3,4]")
|
||||
x.should_receive(:to_ary).at_least(:once).and_return([3, 4])
|
||||
[1, 2, x, 5].flatten.should == [1, 2, 3, 4, 5]
|
||||
|
||||
y = mock("MyArray[]")
|
||||
y.should_receive(:to_ary).at_least(:once).and_return(ArraySpecs::MyArray[])
|
||||
[y].flatten.should == []
|
||||
|
||||
z = mock("[2,x,y,5]")
|
||||
z.should_receive(:to_ary).and_return([2, x, y, 5])
|
||||
[1, z, 6].flatten.should == [1, 2, 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
ruby_version_is "2.3" do
|
||||
it "does not call #to_ary on elements beyond the given level" do
|
||||
obj = mock("1")
|
||||
obj.should_not_receive(:to_ary)
|
||||
[[obj]].flatten(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns subclass instance for Array subclasses" do
|
||||
ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
|
||||
[ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "is not destructive" do
|
||||
ary = [1, [2, 3]]
|
||||
ary.flatten
|
||||
ary.should == [1, [2, 3]]
|
||||
end
|
||||
|
||||
describe "with a non-Array object in the Array" do
|
||||
before :each do
|
||||
@obj = mock("Array#flatten")
|
||||
ScratchPad.record []
|
||||
end
|
||||
|
||||
it "does not call #to_ary if the method is not defined" do
|
||||
[@obj].flatten.should == [@obj]
|
||||
end
|
||||
|
||||
it "does not raise an exception if #to_ary returns nil" do
|
||||
@obj.should_receive(:to_ary).and_return(nil)
|
||||
[@obj].flatten.should == [@obj]
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_ary does not return an Array" do
|
||||
@obj.should_receive(:to_ary).and_return(1)
|
||||
lambda { [@obj].flatten }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not call #to_ary if not defined when #respond_to_missing? returns false" do
|
||||
def @obj.respond_to_missing?(*args) ScratchPad << args; false end
|
||||
|
||||
[@obj].flatten.should == [@obj]
|
||||
ScratchPad.recorded.should == [[:to_ary, false]]
|
||||
end
|
||||
|
||||
it "calls #to_ary if not defined when #respond_to_missing? returns true" do
|
||||
def @obj.respond_to_missing?(*args) ScratchPad << args; true end
|
||||
|
||||
lambda { [@obj].flatten }.should raise_error(NoMethodError)
|
||||
ScratchPad.recorded.should == [[:to_ary, false]]
|
||||
end
|
||||
|
||||
it "calls #method_missing if defined" do
|
||||
@obj.should_receive(:method_missing).with(:to_ary).and_return([1, 2, 3])
|
||||
[@obj].flatten.should == [1, 2, 3]
|
||||
end
|
||||
end
|
||||
|
||||
it "returns a tainted array if self is tainted" do
|
||||
[].taint.flatten.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "returns an untrusted array if self is untrusted" do
|
||||
[].untrust.flatten.untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "performs respond_to? and method_missing-aware checks when coercing elements to array" do
|
||||
bo = BasicObject.new
|
||||
[bo].flatten.should == [bo]
|
||||
|
||||
def bo.method_missing(name, *)
|
||||
[1,2]
|
||||
end
|
||||
|
||||
[bo].flatten.should == [1,2]
|
||||
|
||||
def bo.respond_to?(name, *)
|
||||
false
|
||||
end
|
||||
|
||||
[bo].flatten.should == [bo]
|
||||
|
||||
def bo.respond_to?(name, *)
|
||||
true
|
||||
end
|
||||
|
||||
[bo].flatten.should == [1,2]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#flatten!" do
|
||||
it "modifies array to produce a one-dimensional flattening recursively" do
|
||||
a = [[[1, [2, 3]],[2, 3, [4, [4, [5, 5]], [1, 2, 3]]], [4]], []]
|
||||
a.flatten!
|
||||
a.should == [1, 2, 3, 2, 3, 4, 4, 5, 5, 1, 2, 3, 4]
|
||||
end
|
||||
|
||||
it "returns self if made some modifications" do
|
||||
a = [[[1, [2, 3]],[2, 3, [4, [4, [5, 5]], [1, 2, 3]]], [4]], []]
|
||||
a.flatten!.should equal(a)
|
||||
end
|
||||
|
||||
it "returns nil if no modifications took place" do
|
||||
a = [1, 2, 3]
|
||||
a.flatten!.should == nil
|
||||
a = [1, [2, 3]]
|
||||
a.flatten!.should_not == nil
|
||||
end
|
||||
|
||||
it "should not check modification by size" do
|
||||
a = [1, 2, [3]]
|
||||
a.flatten!.should_not == nil
|
||||
a.should == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "takes an optional argument that determines the level of recursion" do
|
||||
[ 1, 2, [3, [4, 5] ] ].flatten!(1).should == [1, 2, 3, [4, 5]]
|
||||
end
|
||||
|
||||
# redmine #1440
|
||||
it "returns nil when the level of recursion is 0" do
|
||||
a = [ 1, 2, [3, [4, 5] ] ]
|
||||
a.flatten!(0).should == nil
|
||||
end
|
||||
|
||||
it "treats negative levels as no arguments" do
|
||||
[ 1, 2, [ 3, 4, [5, 6] ] ].flatten!(-1).should == [1, 2, 3, 4, 5, 6]
|
||||
[ 1, 2, [ 3, 4, [5, 6] ] ].flatten!(-10).should == [1, 2, 3, 4, 5, 6]
|
||||
end
|
||||
|
||||
it "tries to convert passed Objects to Integers using #to_int" do
|
||||
obj = mock("Converted to Integer")
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
|
||||
[ 1, 2, [3, [4, 5] ] ].flatten!(obj).should == [1, 2, 3, [4, 5]]
|
||||
end
|
||||
|
||||
it "raises a TypeError when the passed Object can't be converted to an Integer" do
|
||||
obj = mock("Not converted")
|
||||
lambda { [ 1, 2, [3, [4, 5] ] ].flatten!(obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not call flatten! on elements" do
|
||||
obj = mock('[1,2]')
|
||||
obj.should_not_receive(:flatten!)
|
||||
[obj, obj].flatten!.should == nil
|
||||
|
||||
obj = [5, 4]
|
||||
obj.should_not_receive(:flatten!)
|
||||
[obj, obj].flatten!.should == [5, 4, 5, 4]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError on recursive arrays" do
|
||||
x = []
|
||||
x << x
|
||||
lambda { x.flatten! }.should raise_error(ArgumentError)
|
||||
|
||||
x = []
|
||||
y = []
|
||||
x << y
|
||||
y << x
|
||||
lambda { x.flatten! }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "flattens any elements which responds to #to_ary, using the return value of said method" do
|
||||
x = mock("[3,4]")
|
||||
x.should_receive(:to_ary).at_least(:once).and_return([3, 4])
|
||||
[1, 2, x, 5].flatten!.should == [1, 2, 3, 4, 5]
|
||||
|
||||
y = mock("MyArray[]")
|
||||
y.should_receive(:to_ary).at_least(:once).and_return(ArraySpecs::MyArray[])
|
||||
[y].flatten!.should == []
|
||||
|
||||
z = mock("[2,x,y,5]")
|
||||
z.should_receive(:to_ary).and_return([2, x, y, 5])
|
||||
[1, z, 6].flatten!.should == [1, 2, 3, 4, 5, 6]
|
||||
|
||||
ary = [ArraySpecs::MyArray[1, 2, 3]]
|
||||
ary.flatten!
|
||||
ary.should be_an_instance_of(Array)
|
||||
ary.should == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on frozen arrays when the array is modified" do
|
||||
nested_ary = [1, 2, []]
|
||||
nested_ary.freeze
|
||||
lambda { nested_ary.flatten! }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23663]
|
||||
it "raises a RuntimeError on frozen arrays when the array would not be modified" do
|
||||
lambda { ArraySpecs.frozen_array.flatten! }.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.empty_frozen_array.flatten! }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
16
spec/ruby/core/array/frozen_spec.rb
Normal file
16
spec/ruby/core/array/frozen_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#frozen?" do
|
||||
it "returns true if array is frozen" do
|
||||
a = [1, 2, 3]
|
||||
a.frozen?.should == false
|
||||
a.freeze
|
||||
a.frozen?.should == true
|
||||
end
|
||||
|
||||
it "returns false for an array being sorted by #sort" do
|
||||
a = [1, 2, 3]
|
||||
a.sort { |x,y| a.frozen?.should == false; x <=> y }
|
||||
end
|
||||
end
|
83
spec/ruby/core/array/hash_spec.rb
Normal file
83
spec/ruby/core/array/hash_spec.rb
Normal file
|
@ -0,0 +1,83 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#hash" do
|
||||
it "returns the same fixnum for arrays with the same content" do
|
||||
[].respond_to?(:hash).should == true
|
||||
|
||||
[[], [1, 2, 3]].each do |ary|
|
||||
ary.hash.should == ary.dup.hash
|
||||
ary.hash.should be_an_instance_of(Fixnum)
|
||||
end
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
lambda { empty.hash }.should_not raise_error
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
lambda { array.hash }.should_not raise_error
|
||||
end
|
||||
|
||||
it "returns the same hash for equal recursive arrays" do
|
||||
rec = []; rec << rec
|
||||
rec.hash.should == [rec].hash
|
||||
rec.hash.should == [[rec]].hash
|
||||
# This is because rec.eql?([[rec]])
|
||||
# Remember that if two objects are eql?
|
||||
# then the need to have the same hash
|
||||
# Check the Array#eql? specs!
|
||||
end
|
||||
|
||||
it "returns the same hash for equal recursive arrays through hashes" do
|
||||
h = {} ; rec = [h] ; h[:x] = rec
|
||||
rec.hash.should == [h].hash
|
||||
rec.hash.should == [{x: rec}].hash
|
||||
# Like above, this is because rec.eql?([{x: rec}])
|
||||
end
|
||||
|
||||
it "calls to_int on result of calling hash on each element" do
|
||||
ary = Array.new(5) do
|
||||
obj = mock('0')
|
||||
obj.should_receive(:hash).and_return(obj)
|
||||
obj.should_receive(:to_int).and_return(0)
|
||||
obj
|
||||
end
|
||||
|
||||
ary.hash
|
||||
|
||||
|
||||
hash = mock('1')
|
||||
hash.should_receive(:to_int).and_return(1.hash)
|
||||
|
||||
obj = mock('@hash')
|
||||
obj.instance_variable_set(:@hash, hash)
|
||||
def obj.hash() @hash end
|
||||
|
||||
[obj].hash.should == [1].hash
|
||||
end
|
||||
|
||||
it "ignores array class differences" do
|
||||
ArraySpecs::MyArray[].hash.should == [].hash
|
||||
ArraySpecs::MyArray[1, 2].hash.should == [1, 2].hash
|
||||
end
|
||||
|
||||
it "returns same hash code for arrays with the same content" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.fill 'a', 0..3
|
||||
b = %w|a a a a|
|
||||
a.hash.should == b.hash
|
||||
end
|
||||
|
||||
it "returns the same value if arrays are #eql?" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.fill 'a', 0..3
|
||||
b = %w|a a a a|
|
||||
a.hash.should == b.hash
|
||||
a.should eql(b)
|
||||
end
|
||||
|
||||
it "produces different hashes for nested arrays with different values and empty terminator" do
|
||||
[1, [1, []]].hash.should_not == [2, [2, []]].hash
|
||||
end
|
||||
end
|
33
spec/ruby/core/array/include_spec.rb
Normal file
33
spec/ruby/core/array/include_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#include?" do
|
||||
it "returns true if object is present, false otherwise" do
|
||||
[1, 2, "a", "b"].include?("c").should == false
|
||||
[1, 2, "a", "b"].include?("a").should == true
|
||||
end
|
||||
|
||||
it "determines presence by using element == obj" do
|
||||
o = mock('')
|
||||
|
||||
[1, 2, "a", "b"].include?(o).should == false
|
||||
|
||||
def o.==(other); other == 'a'; end
|
||||
|
||||
[1, 2, o, "b"].include?('a').should == true
|
||||
|
||||
[1, 2.0, 3].include?(2).should == true
|
||||
end
|
||||
|
||||
it "calls == on elements from left to right until success" do
|
||||
key = "x"
|
||||
one = mock('one')
|
||||
two = mock('two')
|
||||
three = mock('three')
|
||||
one.should_receive(:==).any_number_of_times.and_return(false)
|
||||
two.should_receive(:==).any_number_of_times.and_return(true)
|
||||
three.should_not_receive(:==)
|
||||
ary = [one, two, three]
|
||||
ary.include?(key).should == true
|
||||
end
|
||||
end
|
6
spec/ruby/core/array/index_spec.rb
Normal file
6
spec/ruby/core/array/index_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/index', __FILE__)
|
||||
|
||||
describe "Array#index" do
|
||||
it_behaves_like(:array_index, :index)
|
||||
end
|
156
spec/ruby/core/array/initialize_spec.rb
Normal file
156
spec/ruby/core/array/initialize_spec.rb
Normal file
|
@ -0,0 +1,156 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#initialize" do
|
||||
before :each do
|
||||
ScratchPad.clear
|
||||
end
|
||||
|
||||
it "is private" do
|
||||
Array.should have_private_instance_method("initialize")
|
||||
end
|
||||
|
||||
it "is called on subclasses" do
|
||||
b = ArraySpecs::SubArray.new :size_or_array, :obj
|
||||
|
||||
b.should == []
|
||||
ScratchPad.recorded.should == [:size_or_array, :obj]
|
||||
end
|
||||
|
||||
it "preserves the object's identity even when changing its value" do
|
||||
a = [1, 2, 3]
|
||||
a.send(:initialize).should equal(a)
|
||||
a.should_not == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if passed 3 or more arguments" do
|
||||
lambda do
|
||||
[1, 2].send :initialize, 1, 'x', true
|
||||
end.should raise_error(ArgumentError)
|
||||
lambda do
|
||||
[1, 2].send(:initialize, 1, 'x', true) {}
|
||||
end.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on frozen arrays" do
|
||||
lambda do
|
||||
ArraySpecs.frozen_array.send :initialize
|
||||
end.should raise_error(RuntimeError)
|
||||
lambda do
|
||||
ArraySpecs.frozen_array.send :initialize, ArraySpecs.frozen_array
|
||||
end.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "calls #to_ary to convert the value to an array, even if it's private" do
|
||||
a = ArraySpecs::PrivateToAry.new
|
||||
[].send(:initialize, a).should == [1, 2, 3]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#initialize with no arguments" do
|
||||
it "makes the array empty" do
|
||||
[1, 2, 3].send(:initialize).should be_empty
|
||||
end
|
||||
|
||||
it "does not use the given block" do
|
||||
lambda{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#initialize with (array)" do
|
||||
it "replaces self with the other array" do
|
||||
b = [4, 5, 6]
|
||||
[1, 2, 3].send(:initialize, b).should == b
|
||||
end
|
||||
|
||||
it "does not use the given block" do
|
||||
lambda{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
|
||||
end
|
||||
|
||||
it "calls #to_ary to convert the value to an array" do
|
||||
a = mock("array")
|
||||
a.should_receive(:to_ary).and_return([1, 2])
|
||||
a.should_not_receive(:to_int)
|
||||
[].send(:initialize, a).should == [1, 2]
|
||||
end
|
||||
|
||||
it "does not call #to_ary on instances of Array or subclasses of Array" do
|
||||
a = [1, 2]
|
||||
a.should_not_receive(:to_ary)
|
||||
[].send(:initialize, a).should == a
|
||||
end
|
||||
|
||||
it "raises a TypeError if an Array type argument and a default object" do
|
||||
lambda { [].send(:initialize, [1, 2], 1) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#initialize with (size, object=nil)" do
|
||||
it "sets the array to size and fills with the object" do
|
||||
a = []
|
||||
obj = [3]
|
||||
a.send(:initialize, 2, obj).should == [obj, obj]
|
||||
a[0].should equal(obj)
|
||||
a[1].should equal(obj)
|
||||
|
||||
b = []
|
||||
b.send(:initialize, 3, 14).should == [14, 14, 14]
|
||||
b.should == [14, 14, 14]
|
||||
end
|
||||
|
||||
it "sets the array to size and fills with nil when object is omitted" do
|
||||
[].send(:initialize, 3).should == [nil, nil, nil]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if size is negative" do
|
||||
lambda { [].send(:initialize, -1, :a) }.should raise_error(ArgumentError)
|
||||
lambda { [].send(:initialize, -1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if size is too large" do
|
||||
lambda { [].send(:initialize, fixnum_max+1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the size argument to an Integer when object is given" do
|
||||
obj = mock('1')
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
[].send(:initialize, obj, :a).should == [:a]
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the size argument to an Integer when object is not given" do
|
||||
obj = mock('1')
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
[].send(:initialize, obj).should == [nil]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the size argument is not an Integer type" do
|
||||
obj = mock('nonnumeric')
|
||||
obj.stub!(:to_ary).and_return([1, 2])
|
||||
lambda{ [].send(:initialize, obj, :a) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "yields the index of the element and sets the element to the value of the block" do
|
||||
[].send(:initialize, 3) { |i| i.to_s }.should == ['0', '1', '2']
|
||||
end
|
||||
|
||||
it "uses the block value instead of using the default value" do
|
||||
lambda {
|
||||
@result = [].send(:initialize, 3, :obj) { |i| i.to_s }
|
||||
}.should complain(/block supersedes default value argument/)
|
||||
@result.should == ['0', '1', '2']
|
||||
end
|
||||
|
||||
it "returns the value passed to break" do
|
||||
[].send(:initialize, 3) { break :a }.should == :a
|
||||
end
|
||||
|
||||
it "sets the array to the values returned by the block before break is executed" do
|
||||
a = [1, 2, 3]
|
||||
a.send(:initialize, 3) do |i|
|
||||
break if i == 2
|
||||
i.to_s
|
||||
end
|
||||
|
||||
a.should == ['0', '1']
|
||||
end
|
||||
end
|
78
spec/ruby/core/array/insert_spec.rb
Normal file
78
spec/ruby/core/array/insert_spec.rb
Normal file
|
@ -0,0 +1,78 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#insert" do
|
||||
it "returns self" do
|
||||
ary = []
|
||||
ary.insert(0).should equal(ary)
|
||||
ary.insert(0, :a).should equal(ary)
|
||||
end
|
||||
|
||||
it "inserts objects before the element at index for non-negative index" do
|
||||
ary = []
|
||||
ary.insert(0, 3).should == [3]
|
||||
ary.insert(0, 1, 2).should == [1, 2, 3]
|
||||
ary.insert(0).should == [1, 2, 3]
|
||||
|
||||
# Let's just assume insert() always modifies the array from now on.
|
||||
ary.insert(1, 'a').should == [1, 'a', 2, 3]
|
||||
ary.insert(0, 'b').should == ['b', 1, 'a', 2, 3]
|
||||
ary.insert(5, 'c').should == ['b', 1, 'a', 2, 3, 'c']
|
||||
ary.insert(7, 'd').should == ['b', 1, 'a', 2, 3, 'c', nil, 'd']
|
||||
ary.insert(10, 5, 4).should == ['b', 1, 'a', 2, 3, 'c', nil, 'd', nil, nil, 5, 4]
|
||||
end
|
||||
|
||||
it "appends objects to the end of the array for index == -1" do
|
||||
[1, 3, 3].insert(-1, 2, 'x', 0.5).should == [1, 3, 3, 2, 'x', 0.5]
|
||||
end
|
||||
|
||||
it "inserts objects after the element at index with negative index" do
|
||||
ary = []
|
||||
ary.insert(-1, 3).should == [3]
|
||||
ary.insert(-2, 2).should == [2, 3]
|
||||
ary.insert(-3, 1).should == [1, 2, 3]
|
||||
ary.insert(-2, -3).should == [1, 2, -3, 3]
|
||||
ary.insert(-1, []).should == [1, 2, -3, 3, []]
|
||||
ary.insert(-2, 'x', 'y').should == [1, 2, -3, 3, 'x', 'y', []]
|
||||
ary = [1, 2, 3]
|
||||
end
|
||||
|
||||
it "pads with nils if the index to be inserted to is past the end" do
|
||||
[].insert(5, 5).should == [nil, nil, nil, nil, nil, 5]
|
||||
end
|
||||
|
||||
it "can insert before the first element with a negative index" do
|
||||
[1, 2, 3].insert(-4, -3).should == [-3, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "raises an IndexError if the negative index is out of bounds" do
|
||||
lambda { [].insert(-2, 1) }.should raise_error(IndexError)
|
||||
lambda { [1].insert(-3, 2) }.should raise_error(IndexError)
|
||||
end
|
||||
|
||||
it "does nothing of no object is passed" do
|
||||
[].insert(0).should == []
|
||||
[].insert(-1).should == []
|
||||
[].insert(10).should == []
|
||||
[].insert(-2).should == []
|
||||
end
|
||||
|
||||
it "tries to convert the passed position argument to an Integer using #to_int" do
|
||||
obj = mock('2')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
[].insert(obj, 'x').should == [nil, nil, 'x']
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if no argument passed" do
|
||||
lambda { [].insert() }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on frozen arrays when the array is modified" do
|
||||
lambda { ArraySpecs.frozen_array.insert(0, 'x') }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError on frozen arrays when the array would not be modified" do
|
||||
lambda { ArraySpecs.frozen_array.insert(0) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
7
spec/ruby/core/array/inspect_spec.rb
Normal file
7
spec/ruby/core/array/inspect_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/inspect', __FILE__)
|
||||
|
||||
describe "Array#inspect" do
|
||||
it_behaves_like :array_inspect, :inspect
|
||||
end
|
86
spec/ruby/core/array/intersection_spec.rb
Normal file
86
spec/ruby/core/array/intersection_spec.rb
Normal file
|
@ -0,0 +1,86 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#&" do
|
||||
it "creates an array with elements common to both arrays (intersection)" do
|
||||
([] & []).should == []
|
||||
([1, 2] & []).should == []
|
||||
([] & [1, 2]).should == []
|
||||
([ 1, 3, 5 ] & [ 1, 2, 3 ]).should == [1, 3]
|
||||
end
|
||||
|
||||
it "creates an array with no duplicates" do
|
||||
([ 1, 1, 3, 5 ] & [ 1, 2, 3 ]).uniq!.should == nil
|
||||
end
|
||||
|
||||
it "creates an array with elements in order they are first encountered" do
|
||||
([ 1, 2, 3, 2, 5 ] & [ 5, 2, 3, 4 ]).should == [2, 3, 5]
|
||||
end
|
||||
|
||||
it "does not modify the original Array" do
|
||||
a = [1, 1, 3, 5]
|
||||
a & [1, 2, 3]
|
||||
a.should == [1, 1, 3, 5]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
(empty & empty).should == empty
|
||||
|
||||
(ArraySpecs.recursive_array & []).should == []
|
||||
([] & ArraySpecs.recursive_array).should == []
|
||||
|
||||
(ArraySpecs.recursive_array & ArraySpecs.recursive_array).should == [1, 'two', 3.0, ArraySpecs.recursive_array]
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Array using #to_ary" do
|
||||
obj = mock('[1,2,3]')
|
||||
obj.should_receive(:to_ary).and_return([1, 2, 3])
|
||||
([1, 2] & obj).should == ([1, 2])
|
||||
end
|
||||
|
||||
it "determines equivalence between elements in the sense of eql?" do
|
||||
not_supported_on :opal do
|
||||
([5.0, 4.0] & [5, 4]).should == []
|
||||
end
|
||||
|
||||
str = "x"
|
||||
([str] & [str.dup]).should == [str]
|
||||
|
||||
obj1 = mock('1')
|
||||
obj2 = mock('2')
|
||||
obj1.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj2.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj1.should_receive(:eql?).at_least(1).and_return(true)
|
||||
|
||||
([obj1] & [obj2]).should == [obj1]
|
||||
([obj1, obj1, obj2, obj2] & [obj2]).should == [obj1]
|
||||
|
||||
obj1 = mock('3')
|
||||
obj2 = mock('4')
|
||||
obj1.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj2.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj1.should_receive(:eql?).at_least(1).and_return(false)
|
||||
|
||||
([obj1] & [obj2]).should == []
|
||||
([obj1, obj1, obj2, obj2] & [obj2]).should == [obj2]
|
||||
end
|
||||
|
||||
it "does return subclass instances for Array subclasses" do
|
||||
(ArraySpecs::MyArray[1, 2, 3] & []).should be_an_instance_of(Array)
|
||||
(ArraySpecs::MyArray[1, 2, 3] & ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
|
||||
([] & ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "does not call to_ary on array subclasses" do
|
||||
([5, 6] & ArraySpecs::ToAryArray[1, 2, 5, 6]).should == [5, 6]
|
||||
end
|
||||
|
||||
it "properly handles an identical item even when its #eql? isn't reflexive" do
|
||||
x = mock('x')
|
||||
x.should_receive(:hash).at_least(1).and_return(42)
|
||||
x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
|
||||
|
||||
([x] & [x]).should == [x]
|
||||
end
|
||||
end
|
48
spec/ruby/core/array/join_spec.rb
Normal file
48
spec/ruby/core/array/join_spec.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/join', __FILE__)
|
||||
|
||||
describe "Array#join" do
|
||||
it_behaves_like :array_join_with_string_separator, :join
|
||||
it_behaves_like :array_join_with_default_separator, :join
|
||||
|
||||
it "does not separate elements when the passed separator is nil" do
|
||||
[1, 2, 3].join(nil).should == '123'
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the separator to a String" do
|
||||
sep = mock("separator")
|
||||
sep.should_receive(:to_str).and_return(", ")
|
||||
[1, 2].join(sep).should == "1, 2"
|
||||
end
|
||||
|
||||
it "does not call #to_str on the separator if the array is empty" do
|
||||
sep = mock("separator")
|
||||
sep.should_not_receive(:to_str)
|
||||
[].join(sep).should == ""
|
||||
end
|
||||
|
||||
it "raises a TypeError if the separator cannot be coerced to a String by calling #to_str" do
|
||||
obj = mock("not a string")
|
||||
lambda { [1, 2].join(obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed false as the separator" do
|
||||
lambda { [1, 2].join(false) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#join with $," do
|
||||
before :each do
|
||||
@before_separator = $,
|
||||
end
|
||||
|
||||
after :each do
|
||||
$, = @before_separator
|
||||
end
|
||||
|
||||
it "separates elements with default separator when the passed separator is nil" do
|
||||
$, = "_"
|
||||
[1, 2, 3].join(nil).should == '1_2_3'
|
||||
end
|
||||
end
|
10
spec/ruby/core/array/keep_if_spec.rb
Normal file
10
spec/ruby/core/array/keep_if_spec.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require File.expand_path('../shared/keep_if', __FILE__)
|
||||
|
||||
describe "Array#keep_if" do
|
||||
it "returns the same array if no changes were made" do
|
||||
array = [1, 2, 3]
|
||||
array.keep_if { true }.should equal(array)
|
||||
end
|
||||
|
||||
it_behaves_like :keep_if, :keep_if
|
||||
end
|
87
spec/ruby/core/array/last_spec.rb
Normal file
87
spec/ruby/core/array/last_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#last" do
|
||||
it "returns the last element" do
|
||||
[1, 1, 1, 1, 2].last.should == 2
|
||||
end
|
||||
|
||||
it "returns nil if self is empty" do
|
||||
[].last.should == nil
|
||||
end
|
||||
|
||||
it "returns the last count elements if given a count" do
|
||||
[1, 2, 3, 4, 5, 9].last(3).should == [4, 5, 9]
|
||||
end
|
||||
|
||||
it "returns an empty array when passed a count on an empty array" do
|
||||
[].last(0).should == []
|
||||
[].last(1).should == []
|
||||
end
|
||||
|
||||
it "returns an empty array when count == 0" do
|
||||
[1, 2, 3, 4, 5].last(0).should == []
|
||||
end
|
||||
|
||||
it "returns an array containing the last element when passed count == 1" do
|
||||
[1, 2, 3, 4, 5].last(1).should == [5]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when count is negative" do
|
||||
lambda { [1, 2].last(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns the entire array when count > length" do
|
||||
[1, 2, 3, 4, 5, 9].last(10).should == [1, 2, 3, 4, 5, 9]
|
||||
end
|
||||
|
||||
it "returns an array which is independent to the original when passed count" do
|
||||
ary = [1, 2, 3, 4, 5]
|
||||
ary.last(0).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
ary.last(1).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
ary.last(6).replace([1,2])
|
||||
ary.should == [1, 2, 3, 4, 5]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.last.should equal(empty)
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.last.should equal(array)
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Integer usinig #to_int" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
[1, 2, 3, 4, 5].last(obj).should == [4, 5]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the passed argument is not numeric" do
|
||||
lambda { [1,2].last(nil) }.should raise_error(TypeError)
|
||||
lambda { [1,2].last("a") }.should raise_error(TypeError)
|
||||
|
||||
obj = mock("nonnumeric")
|
||||
lambda { [1,2].last(obj) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not return subclass instance on Array subclasses" do
|
||||
ArraySpecs::MyArray[].last(0).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[].last(2).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].last(0).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].last(1).should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].last(2).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "is not destructive" do
|
||||
a = [1, 2, 3]
|
||||
a.last
|
||||
a.should == [1, 2, 3]
|
||||
a.last(2)
|
||||
a.should == [1, 2, 3]
|
||||
a.last(3)
|
||||
a.should == [1, 2, 3]
|
||||
end
|
||||
end
|
7
spec/ruby/core/array/length_spec.rb
Normal file
7
spec/ruby/core/array/length_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/length', __FILE__)
|
||||
|
||||
describe "Array#length" do
|
||||
it_behaves_like(:array_length, :length)
|
||||
end
|
11
spec/ruby/core/array/map_spec.rb
Normal file
11
spec/ruby/core/array/map_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/collect', __FILE__)
|
||||
|
||||
describe "Array#map" do
|
||||
it_behaves_like(:array_collect, :map)
|
||||
end
|
||||
|
||||
describe "Array#map!" do
|
||||
it_behaves_like(:array_collect_b, :map!)
|
||||
end
|
112
spec/ruby/core/array/max_spec.rb
Normal file
112
spec/ruby/core/array/max_spec.rb
Normal file
|
@ -0,0 +1,112 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#max" do
|
||||
it "returns nil with no values" do
|
||||
[].max.should == nil
|
||||
end
|
||||
|
||||
it "returns only element in one element array" do
|
||||
[1].max.should == 1
|
||||
end
|
||||
|
||||
it "returns largest value with multiple elements" do
|
||||
[1,2].max.should == 2
|
||||
[2,1].max.should == 2
|
||||
end
|
||||
|
||||
describe "given a block with one argument" do
|
||||
it "yields in turn the last length-1 values from the array" do
|
||||
ary = []
|
||||
result = [1,2,3,4,5].max {|x| ary << x; x}
|
||||
|
||||
ary.should == [2,3,4,5]
|
||||
result.should == 5
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# From Enumerable#max, copied for better readability
|
||||
describe "Array#max" do
|
||||
before :each do
|
||||
@a = [2, 4, 6, 8, 10]
|
||||
|
||||
@e_strs = ["333", "22", "666666", "1", "55555", "1010101010"]
|
||||
@e_ints = [333, 22, 666666, 55555, 1010101010]
|
||||
end
|
||||
|
||||
it "max should return the maximum element" do
|
||||
[18, 42].max.should == 42
|
||||
[2, 5, 3, 6, 1, 4].max.should == 6
|
||||
end
|
||||
|
||||
it "returns the maximum element (basics cases)" do
|
||||
[55].max.should == 55
|
||||
|
||||
[11,99].max.should == 99
|
||||
[99,11].max.should == 99
|
||||
[2, 33, 4, 11].max.should == 33
|
||||
|
||||
[1,2,3,4,5].max.should == 5
|
||||
[5,4,3,2,1].max.should == 5
|
||||
[1,4,3,5,2].max.should == 5
|
||||
[5,5,5,5,5].max.should == 5
|
||||
|
||||
["aa","tt"].max.should == "tt"
|
||||
["tt","aa"].max.should == "tt"
|
||||
["2","33","4","11"].max.should == "4"
|
||||
|
||||
@e_strs.max.should == "666666"
|
||||
@e_ints.max.should == 1010101010
|
||||
end
|
||||
|
||||
it "returns nil for an empty Enumerable" do
|
||||
[].max.should == nil
|
||||
end
|
||||
|
||||
it "raises a NoMethodError for elements without #<=>" do
|
||||
lambda do
|
||||
[BasicObject.new, BasicObject.new].max
|
||||
end.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError for incomparable elements" do
|
||||
lambda do
|
||||
[11,"22"].max
|
||||
end.should raise_error(ArgumentError)
|
||||
lambda do
|
||||
[11,12,22,33].max{|a, b| nil}
|
||||
end.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns the maximum element (with block)" do
|
||||
# with a block
|
||||
["2","33","4","11"].max {|a,b| a <=> b }.should == "4"
|
||||
[ 2 , 33 , 4 , 11 ].max {|a,b| a <=> b }.should == 33
|
||||
|
||||
["2","33","4","11"].max {|a,b| b <=> a }.should == "11"
|
||||
[ 2 , 33 , 4 , 11 ].max {|a,b| b <=> a }.should == 2
|
||||
|
||||
@e_strs.max {|a,b| a.length <=> b.length }.should == "1010101010"
|
||||
|
||||
@e_strs.max {|a,b| a <=> b }.should == "666666"
|
||||
@e_strs.max {|a,b| a.to_i <=> b.to_i }.should == "1010101010"
|
||||
|
||||
@e_ints.max {|a,b| a <=> b }.should == 1010101010
|
||||
@e_ints.max {|a,b| a.to_s <=> b.to_s }.should == 666666
|
||||
end
|
||||
|
||||
it "returns the minimum for enumerables that contain nils" do
|
||||
arr = [nil, nil, true]
|
||||
arr.max { |a, b|
|
||||
x = a.nil? ? 1 : a ? 0 : -1
|
||||
y = b.nil? ? 1 : b ? 0 : -1
|
||||
x <=> y
|
||||
}.should == nil
|
||||
end
|
||||
|
||||
it "gathers whole arrays as elements when each yields multiple" do
|
||||
multi = [[1,2], [3,4,5], [6,7,8,9]]
|
||||
multi.max.should == [6, 7, 8, 9]
|
||||
end
|
||||
|
||||
end
|
117
spec/ruby/core/array/min_spec.rb
Normal file
117
spec/ruby/core/array/min_spec.rb
Normal file
|
@ -0,0 +1,117 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#min" do
|
||||
it "returns nil with no values" do
|
||||
[].min.should == nil
|
||||
end
|
||||
|
||||
it "returns only element in one element array" do
|
||||
[1].min.should == 1
|
||||
end
|
||||
|
||||
it "returns smallest value with multiple elements" do
|
||||
[1,2].min.should == 1
|
||||
[2,1].min.should == 1
|
||||
end
|
||||
|
||||
describe "given a block with one argument" do
|
||||
it "yields in turn the last length-1 values from the array" do
|
||||
ary = []
|
||||
result = [1,2,3,4,5].min {|x| ary << x; x}
|
||||
|
||||
ary.should == [2,3,4,5]
|
||||
result.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# From Enumerable#min, copied for better readability
|
||||
describe "Array#min" do
|
||||
before :each do
|
||||
@a = [2, 4, 6, 8, 10]
|
||||
|
||||
@e_strs = ["333", "22", "666666", "1", "55555", "1010101010"]
|
||||
@e_ints = [ 333, 22, 666666, 55555, 1010101010]
|
||||
end
|
||||
|
||||
it "min should return the minimum element" do
|
||||
[18, 42].min.should == 18
|
||||
[2, 5, 3, 6, 1, 4].min.should == 1
|
||||
end
|
||||
|
||||
it "returns the minimum (basic cases)" do
|
||||
[55].min.should == 55
|
||||
|
||||
[11,99].min.should == 11
|
||||
[99,11].min.should == 11
|
||||
[2, 33, 4, 11].min.should == 2
|
||||
|
||||
[1,2,3,4,5].min.should == 1
|
||||
[5,4,3,2,1].min.should == 1
|
||||
[4,1,3,5,2].min.should == 1
|
||||
[5,5,5,5,5].min.should == 5
|
||||
|
||||
["aa","tt"].min.should == "aa"
|
||||
["tt","aa"].min.should == "aa"
|
||||
["2","33","4","11"].min.should == "11"
|
||||
|
||||
@e_strs.min.should == "1"
|
||||
@e_ints.min.should == 22
|
||||
end
|
||||
|
||||
it "returns nil for an empty Enumerable" do
|
||||
[].min.should be_nil
|
||||
end
|
||||
|
||||
it "raises a NoMethodError for elements without #<=>" do
|
||||
lambda do
|
||||
[BasicObject.new, BasicObject.new].min
|
||||
end.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError for incomparable elements" do
|
||||
lambda do
|
||||
[11,"22"].min
|
||||
end.should raise_error(ArgumentError)
|
||||
lambda do
|
||||
[11,12,22,33].min{|a, b| nil}
|
||||
end.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns the minimum when using a block rule" do
|
||||
["2","33","4","11"].min {|a,b| a <=> b }.should == "11"
|
||||
[ 2 , 33 , 4 , 11 ].min {|a,b| a <=> b }.should == 2
|
||||
|
||||
["2","33","4","11"].min {|a,b| b <=> a }.should == "4"
|
||||
[ 2 , 33 , 4 , 11 ].min {|a,b| b <=> a }.should == 33
|
||||
|
||||
[ 1, 2, 3, 4 ].min {|a,b| 15 }.should == 1
|
||||
|
||||
[11,12,22,33].min{|a, b| 2 }.should == 11
|
||||
@i = -2
|
||||
[11,12,22,33].min{|a, b| @i += 1 }.should == 12
|
||||
|
||||
@e_strs.min {|a,b| a.length <=> b.length }.should == "1"
|
||||
|
||||
@e_strs.min {|a,b| a <=> b }.should == "1"
|
||||
@e_strs.min {|a,b| a.to_i <=> b.to_i }.should == "1"
|
||||
|
||||
@e_ints.min {|a,b| a <=> b }.should == 22
|
||||
@e_ints.min {|a,b| a.to_s <=> b.to_s }.should == 1010101010
|
||||
end
|
||||
|
||||
it "returns the minimum for enumerables that contain nils" do
|
||||
arr = [nil, nil, true]
|
||||
arr.min { |a, b|
|
||||
x = a.nil? ? -1 : a ? 0 : 1
|
||||
y = b.nil? ? -1 : b ? 0 : 1
|
||||
x <=> y
|
||||
}.should == nil
|
||||
end
|
||||
|
||||
it "gathers whole arrays as elements when each yields multiple" do
|
||||
multi = [[1,2], [3,4,5], [6,7,8,9]]
|
||||
multi.min.should == [1, 2]
|
||||
end
|
||||
|
||||
end
|
87
spec/ruby/core/array/minus_spec.rb
Normal file
87
spec/ruby/core/array/minus_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#-" do
|
||||
it "creates an array minus any items from other array" do
|
||||
([] - [ 1, 2, 4 ]).should == []
|
||||
([1, 2, 4] - []).should == [1, 2, 4]
|
||||
([ 1, 2, 3, 4, 5 ] - [ 1, 2, 4 ]).should == [3, 5]
|
||||
end
|
||||
|
||||
it "removes multiple items on the lhs equal to one on the rhs" do
|
||||
([1, 1, 2, 2, 3, 3, 4, 5] - [1, 2, 4]).should == [3, 3, 5]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
(empty - empty).should == []
|
||||
|
||||
([] - ArraySpecs.recursive_array).should == []
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
(array - array).should == []
|
||||
end
|
||||
|
||||
it "tries to convert the passed arguments to Arrays using #to_ary" do
|
||||
obj = mock('[2,3,3,4]')
|
||||
obj.should_receive(:to_ary).and_return([2, 3, 3, 4])
|
||||
([1, 1, 2, 2, 3, 4] - obj).should == [1, 1]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the argument cannot be coerced to an Array by calling #to_ary" do
|
||||
obj = mock('not an array')
|
||||
lambda { [1, 2, 3] - obj }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not return subclass instance for Array subclasses" do
|
||||
(ArraySpecs::MyArray[1, 2, 3] - []).should be_an_instance_of(Array)
|
||||
(ArraySpecs::MyArray[1, 2, 3] - ArraySpecs::MyArray[]).should be_an_instance_of(Array)
|
||||
([1, 2, 3] - ArraySpecs::MyArray[]).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "does not call to_ary on array subclasses" do
|
||||
([5, 6, 7] - ArraySpecs::ToAryArray[7]).should == [5, 6]
|
||||
end
|
||||
|
||||
it "removes an item identified as equivalent via #hash and #eql?" do
|
||||
obj1 = mock('1')
|
||||
obj2 = mock('2')
|
||||
obj1.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj2.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj1.should_receive(:eql?).at_least(1).and_return(true)
|
||||
|
||||
([obj1] - [obj2]).should == []
|
||||
([obj1, obj1, obj2, obj2] - [obj2]).should == []
|
||||
end
|
||||
|
||||
it "doesn't remove an item with the same hash but not #eql?" do
|
||||
obj1 = mock('1')
|
||||
obj2 = mock('2')
|
||||
obj1.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj2.should_receive(:hash).at_least(1).and_return(0)
|
||||
obj1.should_receive(:eql?).at_least(1).and_return(false)
|
||||
|
||||
([obj1] - [obj2]).should == [obj1]
|
||||
([obj1, obj1, obj2, obj2] - [obj2]).should == [obj1, obj1]
|
||||
end
|
||||
|
||||
it "removes an identical item even when its #eql? isn't reflexive" do
|
||||
x = mock('x')
|
||||
x.should_receive(:hash).at_least(1).and_return(42)
|
||||
x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
|
||||
|
||||
([x] - [x]).should == []
|
||||
end
|
||||
|
||||
it "is not destructive" do
|
||||
a = [1, 2, 3]
|
||||
a - []
|
||||
a.should == [1, 2, 3]
|
||||
a - [1]
|
||||
a.should == [1, 2, 3]
|
||||
a - [1,2,3]
|
||||
a.should == [1, 2, 3]
|
||||
a - [:a, :b, :c]
|
||||
a.should == [1, 2, 3]
|
||||
end
|
||||
end
|
132
spec/ruby/core/array/multiply_spec.rb
Normal file
132
spec/ruby/core/array/multiply_spec.rb
Normal file
|
@ -0,0 +1,132 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/join', __FILE__)
|
||||
|
||||
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')
|
||||
lambda{ [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
|
||||
lambda{ [1,2] * nil }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed 2 or more arguments" do
|
||||
lambda{ [1,2].send(:*, 1, 2) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed no arguments" do
|
||||
lambda{ [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
|
||||
lambda { [ 1, 2, 3 ] * -1 }.should raise_error(ArgumentError)
|
||||
lambda { [] * -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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
it "copies the taint status of the original array even if the passed count is 0" do
|
||||
ary = [1, 2, 3]
|
||||
ary.taint
|
||||
(ary * 0).tainted?.should == true
|
||||
end
|
||||
|
||||
it "copies the taint status of the original array even if the array is empty" do
|
||||
ary = []
|
||||
ary.taint
|
||||
(ary * 3).tainted?.should == true
|
||||
end
|
||||
|
||||
it "copies the taint status of the original array if the passed count is not 0" do
|
||||
ary = [1, 2, 3]
|
||||
ary.taint
|
||||
(ary * 1).tainted?.should == true
|
||||
(ary * 2).tainted?.should == true
|
||||
end
|
||||
|
||||
it "copies the untrusted status of the original array even if the passed count is 0" do
|
||||
ary = [1, 2, 3]
|
||||
ary.untrust
|
||||
(ary * 0).untrusted?.should == true
|
||||
end
|
||||
|
||||
it "copies the untrusted status of the original array even if the array is empty" do
|
||||
ary = []
|
||||
ary.untrust
|
||||
(ary * 3).untrusted?.should == true
|
||||
end
|
||||
|
||||
it "copies the untrusted status of the original array if the passed count is not 0" do
|
||||
ary = [1, 2, 3]
|
||||
ary.untrust
|
||||
(ary * 1).untrusted?.should == true
|
||||
(ary * 2).untrusted?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#* with a string" do
|
||||
it_behaves_like :array_join_with_string_separator, :*
|
||||
end
|
122
spec/ruby/core/array/new_spec.rb
Normal file
122
spec/ruby/core/array/new_spec.rb
Normal file
|
@ -0,0 +1,122 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array.new" do
|
||||
it "returns an instance of Array" do
|
||||
Array.new.should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "returns an instance of a subclass" do
|
||||
ArraySpecs::MyArray.new(1, 2).should be_an_instance_of(ArraySpecs::MyArray)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if passed 3 or more arguments" do
|
||||
lambda do
|
||||
[1, 2].send :initialize, 1, 'x', true
|
||||
end.should raise_error(ArgumentError)
|
||||
lambda do
|
||||
[1, 2].send(:initialize, 1, 'x', true) {}
|
||||
end.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array.new with no arguments" do
|
||||
it "returns an empty array" do
|
||||
Array.new.should be_empty
|
||||
end
|
||||
|
||||
it "does not use the given block" do
|
||||
lambda{ Array.new { raise } }.should_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array.new with (array)" do
|
||||
it "returns an array initialized to the other array" do
|
||||
b = [4, 5, 6]
|
||||
Array.new(b).should == b
|
||||
end
|
||||
|
||||
it "does not use the given block" do
|
||||
lambda{ Array.new([1, 2]) { raise } }.should_not raise_error
|
||||
end
|
||||
|
||||
it "calls #to_ary to convert the value to an array" do
|
||||
a = mock("array")
|
||||
a.should_receive(:to_ary).and_return([1, 2])
|
||||
a.should_not_receive(:to_int)
|
||||
Array.new(a).should == [1, 2]
|
||||
end
|
||||
|
||||
it "does not call #to_ary on instances of Array or subclasses of Array" do
|
||||
a = [1, 2]
|
||||
a.should_not_receive(:to_ary)
|
||||
Array.new(a)
|
||||
end
|
||||
|
||||
it "raises a TypeError if an Array type argument and a default object" do
|
||||
lambda { Array.new([1, 2], 1) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array.new with (size, object=nil)" do
|
||||
it "returns an array of size filled with object" do
|
||||
obj = [3]
|
||||
a = Array.new(2, obj)
|
||||
a.should == [obj, obj]
|
||||
a[0].should equal(obj)
|
||||
a[1].should equal(obj)
|
||||
|
||||
Array.new(3, 14).should == [14, 14, 14]
|
||||
end
|
||||
|
||||
it "returns an array of size filled with nil when object is omitted" do
|
||||
Array.new(3).should == [nil, nil, nil]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if size is negative" do
|
||||
lambda { Array.new(-1, :a) }.should raise_error(ArgumentError)
|
||||
lambda { Array.new(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if size is too large" do
|
||||
lambda { Array.new(fixnum_max+1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the size argument to an Integer when object is given" do
|
||||
obj = mock('1')
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
Array.new(obj, :a).should == [:a]
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the size argument to an Integer when object is not given" do
|
||||
obj = mock('1')
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
Array.new(obj).should == [nil]
|
||||
end
|
||||
|
||||
it "raises a TypeError if the size argument is not an Integer type" do
|
||||
obj = mock('nonnumeric')
|
||||
obj.stub!(:to_ary).and_return([1, 2])
|
||||
lambda{ Array.new(obj, :a) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "yields the index of the element and sets the element to the value of the block" do
|
||||
Array.new(3) { |i| i.to_s }.should == ['0', '1', '2']
|
||||
end
|
||||
|
||||
it "uses the block value instead of using the default value" do
|
||||
lambda {
|
||||
@result = Array.new(3, :obj) { |i| i.to_s }
|
||||
}.should complain(/block supersedes default value argument/)
|
||||
@result.should == ['0', '1', '2']
|
||||
end
|
||||
|
||||
it "returns the value passed to break" do
|
||||
a = Array.new(3) do |i|
|
||||
break if i == 2
|
||||
i.to_s
|
||||
end
|
||||
|
||||
a.should == nil
|
||||
end
|
||||
end
|
59
spec/ruby/core/array/pack/a_spec.rb
Normal file
59
spec/ruby/core/array/pack/a_spec.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/string', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'A'" do
|
||||
it_behaves_like :array_pack_basic, 'A'
|
||||
it_behaves_like :array_pack_basic_non_float, 'A'
|
||||
it_behaves_like :array_pack_no_platform, 'A'
|
||||
it_behaves_like :array_pack_string, 'A'
|
||||
|
||||
it "adds all the bytes to the output when passed the '*' modifier" do
|
||||
["abc"].pack("A*").should == "abc"
|
||||
end
|
||||
|
||||
it "padds the output with spaces when the count exceeds the size of the String" do
|
||||
["abc"].pack("A6").should == "abc "
|
||||
end
|
||||
|
||||
it "adds a space when the value is nil" do
|
||||
[nil].pack("A").should == " "
|
||||
end
|
||||
|
||||
it "pads the output with spaces when the value is nil" do
|
||||
[nil].pack("A3").should == " "
|
||||
end
|
||||
|
||||
it "does not pad with spaces when passed the '*' modifier and the value is nil" do
|
||||
[nil].pack("A*").should == ""
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'a'" do
|
||||
it_behaves_like :array_pack_basic, 'a'
|
||||
it_behaves_like :array_pack_basic_non_float, 'a'
|
||||
it_behaves_like :array_pack_no_platform, 'a'
|
||||
it_behaves_like :array_pack_string, 'a'
|
||||
|
||||
it "adds all the bytes to the output when passed the '*' modifier" do
|
||||
["abc"].pack("a*").should == "abc"
|
||||
end
|
||||
|
||||
it "padds the output with NULL bytes when the count exceeds the size of the String" do
|
||||
["abc"].pack("a6").should == "abc\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "adds a NULL byte when the value is nil" do
|
||||
[nil].pack("a").should == "\x00"
|
||||
end
|
||||
|
||||
it "pads the output with NULL bytes when the value is nil" do
|
||||
[nil].pack("a3").should == "\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "does not pad with NULL bytes when passed the '*' modifier and the value is nil" do
|
||||
[nil].pack("a*").should == ""
|
||||
end
|
||||
end
|
30
spec/ruby/core/array/pack/at_spec.rb
Normal file
30
spec/ruby/core/array/pack/at_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
|
||||
describe "Array#pack with format '@'" do
|
||||
it_behaves_like :array_pack_basic, '@'
|
||||
it_behaves_like :array_pack_basic_non_float, '@'
|
||||
it_behaves_like :array_pack_no_platform, '@'
|
||||
|
||||
it "moves the insertion point to the index specified by the count modifier" do
|
||||
[1, 2, 3, 4, 5].pack("C4@2C").should == "\x01\x02\x05"
|
||||
end
|
||||
|
||||
it "does not consume any elements" do
|
||||
[1, 2, 3].pack("C@3C").should == "\x01\x00\x00\x02"
|
||||
end
|
||||
|
||||
it "extends the string with NULL bytes if the string size is less than the count" do
|
||||
[1, 2, 3].pack("@3C*").should == "\x00\x00\x00\x01\x02\x03"
|
||||
end
|
||||
|
||||
it "truncates the string if the string size is greater than the count" do
|
||||
[1, 2, 3].pack("Cx5@2C").should == "\x01\x00\x02"
|
||||
end
|
||||
|
||||
it "implicitly has a count of one when no count modifier is passed" do
|
||||
[1, 2, 3].pack("C*@").should == "\x01"
|
||||
end
|
||||
end
|
105
spec/ruby/core/array/pack/b_spec.rb
Normal file
105
spec/ruby/core/array/pack/b_spec.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/encodings', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'B'" do
|
||||
it_behaves_like :array_pack_basic, 'B'
|
||||
it_behaves_like :array_pack_basic_non_float, 'B'
|
||||
it_behaves_like :array_pack_arguments, 'B'
|
||||
it_behaves_like :array_pack_hex, 'B'
|
||||
|
||||
it "calls #to_str to convert an Object to a String" do
|
||||
obj = mock("pack H string")
|
||||
obj.should_receive(:to_str).and_return("``abcdef")
|
||||
[obj].pack("B*").should == "\x2a"
|
||||
end
|
||||
|
||||
it "encodes one bit for each character starting with the most significant bit" do
|
||||
[ [["0"], "\x00"],
|
||||
[["1"], "\x80"]
|
||||
].should be_computed_by(:pack, "B")
|
||||
end
|
||||
|
||||
it "implicitly has a count of one when not passed a count modifier" do
|
||||
["1"].pack("B").should == "\x80"
|
||||
end
|
||||
|
||||
it "implicitly has count equal to the string length when passed the '*' modifier" do
|
||||
[ [["00101010"], "\x2a"],
|
||||
[["00000000"], "\x00"],
|
||||
[["11111111"], "\xff"],
|
||||
[["10000000"], "\x80"],
|
||||
[["00000001"], "\x01"]
|
||||
].should be_computed_by(:pack, "B*")
|
||||
end
|
||||
|
||||
it "encodes the least significant bit of a character other than 0 or 1" do
|
||||
[ [["bbababab"], "\x2a"],
|
||||
[["^&#&#^#^"], "\x2a"],
|
||||
[["(()()()("], "\x2a"],
|
||||
[["@@%@%@%@"], "\x2a"],
|
||||
[["ppqrstuv"], "\x2a"],
|
||||
[["rqtvtrqp"], "\x42"]
|
||||
].should be_computed_by(:pack, "B*")
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
["1"].pack("B").encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
|
||||
it "encodes the string as a sequence of bytes" do
|
||||
["ああああああああ"].pack("B*").should == "\xdbm\xb6"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'b'" do
|
||||
it_behaves_like :array_pack_basic, 'b'
|
||||
it_behaves_like :array_pack_basic_non_float, 'b'
|
||||
it_behaves_like :array_pack_arguments, 'b'
|
||||
it_behaves_like :array_pack_hex, 'b'
|
||||
|
||||
it "calls #to_str to convert an Object to a String" do
|
||||
obj = mock("pack H string")
|
||||
obj.should_receive(:to_str).and_return("`abcdef`")
|
||||
[obj].pack("b*").should == "\x2a"
|
||||
end
|
||||
|
||||
it "encodes one bit for each character starting with the least significant bit" do
|
||||
[ [["0"], "\x00"],
|
||||
[["1"], "\x01"]
|
||||
].should be_computed_by(:pack, "b")
|
||||
end
|
||||
|
||||
it "implicitly has a count of one when not passed a count modifier" do
|
||||
["1"].pack("b").should == "\x01"
|
||||
end
|
||||
|
||||
it "implicitly has count equal to the string length when passed the '*' modifier" do
|
||||
[ [["0101010"], "\x2a"],
|
||||
[["00000000"], "\x00"],
|
||||
[["11111111"], "\xff"],
|
||||
[["10000000"], "\x01"],
|
||||
[["00000001"], "\x80"]
|
||||
].should be_computed_by(:pack, "b*")
|
||||
end
|
||||
|
||||
it "encodes the least significant bit of a character other than 0 or 1" do
|
||||
[ [["bababab"], "\x2a"],
|
||||
[["&#&#^#^"], "\x2a"],
|
||||
[["()()()("], "\x2a"],
|
||||
[["@%@%@%@"], "\x2a"],
|
||||
[["pqrstuv"], "\x2a"],
|
||||
[["qrtrtvs"], "\x41"]
|
||||
].should be_computed_by(:pack, "b*")
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
["1"].pack("b").encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
|
||||
it "encodes the string as a sequence of bytes" do
|
||||
["ああああああああ"].pack("b*").should == "\xdb\xb6m"
|
||||
end
|
||||
end
|
75
spec/ruby/core/array/pack/c_spec.rb
Normal file
75
spec/ruby/core/array/pack/c_spec.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
|
||||
describe :array_pack_8bit, shared: true do
|
||||
it "encodes the least significant eight bits of a positive number" do
|
||||
[ [[49], "1"],
|
||||
[[0b11111111], "\xFF"],
|
||||
[[0b100000000], "\x00"],
|
||||
[[0b100000001], "\x01"]
|
||||
].should be_computed_by(:pack, pack_format)
|
||||
end
|
||||
|
||||
it "encodes the least significant eight bits of a negative number" do
|
||||
[ [[-1], "\xFF"],
|
||||
[[-0b10000000], "\x80"],
|
||||
[[-0b11111111], "\x01"],
|
||||
[[-0b100000000], "\x00"],
|
||||
[[-0b100000001], "\xFF"]
|
||||
].should be_computed_by(:pack, pack_format)
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[5.2], "\x05"],
|
||||
[[5.8], "\x05"]
|
||||
].should be_computed_by(:pack, pack_format)
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(5)
|
||||
[obj].pack(pack_format).should == "\x05"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[ [[1, 2, 3], pack_format(3), "\x01\x02\x03"],
|
||||
[[1, 2, 3], pack_format(2) + pack_format(1), "\x01\x02\x03"]
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[1, 2, 3, 4, 5].pack(pack_format('*')).should == "\x01\x02\x03\x04\x05"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[1, 2, 3].pack(pack_format("\000", 2)).should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[1, 2, 3].pack(pack_format(' ', 2)).should == "\x01\x02"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'C'" do
|
||||
it_behaves_like :array_pack_basic, 'C'
|
||||
it_behaves_like :array_pack_basic_non_float, 'C'
|
||||
it_behaves_like :array_pack_8bit, 'C'
|
||||
it_behaves_like :array_pack_arguments, 'C'
|
||||
it_behaves_like :array_pack_numeric_basic, 'C'
|
||||
it_behaves_like :array_pack_integer, 'C'
|
||||
it_behaves_like :array_pack_no_platform, 'C'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'c'" do
|
||||
it_behaves_like :array_pack_basic, 'c'
|
||||
it_behaves_like :array_pack_basic_non_float, 'c'
|
||||
it_behaves_like :array_pack_8bit, 'c'
|
||||
it_behaves_like :array_pack_arguments, 'c'
|
||||
it_behaves_like :array_pack_numeric_basic, 'c'
|
||||
it_behaves_like :array_pack_integer, 'c'
|
||||
it_behaves_like :array_pack_no_platform, 'c'
|
||||
end
|
25
spec/ruby/core/array/pack/comment_spec.rb
Normal file
25
spec/ruby/core/array/pack/comment_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#pack" do
|
||||
it "ignores directives text from '#' to the first newline" do
|
||||
[1, 2, 3].pack("c#this is a comment\nc").should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "ignores directives text from '#' to the end if no newline is present" do
|
||||
[1, 2, 3].pack("c#this is a comment c").should == "\x01"
|
||||
end
|
||||
|
||||
it "ignores comments at the start of the directives string" do
|
||||
[1, 2, 3].pack("#this is a comment\nc").should == "\x01"
|
||||
end
|
||||
|
||||
it "ignores the entire directive string if it is a comment" do
|
||||
[1, 2, 3].pack("#this is a comment").should == ""
|
||||
end
|
||||
|
||||
it "ignores multiple comments" do
|
||||
[1, 2, 3].pack("c#comment\nc#comment\nc#c").should == "\x01\x02\x03"
|
||||
end
|
||||
end
|
39
spec/ruby/core/array/pack/d_spec.rb
Normal file
39
spec/ruby/core/array/pack/d_spec.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/float', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'D'" do
|
||||
it_behaves_like :array_pack_basic, 'D'
|
||||
it_behaves_like :array_pack_basic_float, 'D'
|
||||
it_behaves_like :array_pack_arguments, 'D'
|
||||
it_behaves_like :array_pack_no_platform, 'D'
|
||||
it_behaves_like :array_pack_numeric_basic, 'D'
|
||||
it_behaves_like :array_pack_float, 'D'
|
||||
|
||||
little_endian do
|
||||
it_behaves_like :array_pack_double_le, 'D'
|
||||
end
|
||||
|
||||
big_endian do
|
||||
it_behaves_like :array_pack_double_be, 'D'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'd'" do
|
||||
it_behaves_like :array_pack_basic, 'd'
|
||||
it_behaves_like :array_pack_basic_float, 'd'
|
||||
it_behaves_like :array_pack_arguments, 'd'
|
||||
it_behaves_like :array_pack_no_platform, 'd'
|
||||
it_behaves_like :array_pack_numeric_basic, 'd'
|
||||
it_behaves_like :array_pack_float, 'd'
|
||||
|
||||
little_endian do
|
||||
it_behaves_like :array_pack_double_le, 'd'
|
||||
end
|
||||
|
||||
big_endian do
|
||||
it_behaves_like :array_pack_double_be, 'd'
|
||||
end
|
||||
end
|
25
spec/ruby/core/array/pack/e_spec.rb
Normal file
25
spec/ruby/core/array/pack/e_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/float', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'E'" do
|
||||
it_behaves_like :array_pack_basic, 'E'
|
||||
it_behaves_like :array_pack_basic_float, 'E'
|
||||
it_behaves_like :array_pack_arguments, 'E'
|
||||
it_behaves_like :array_pack_no_platform, 'E'
|
||||
it_behaves_like :array_pack_numeric_basic, 'E'
|
||||
it_behaves_like :array_pack_float, 'E'
|
||||
it_behaves_like :array_pack_double_le, 'E'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'e'" do
|
||||
it_behaves_like :array_pack_basic, 'e'
|
||||
it_behaves_like :array_pack_basic_float, 'e'
|
||||
it_behaves_like :array_pack_arguments, 'e'
|
||||
it_behaves_like :array_pack_no_platform, 'e'
|
||||
it_behaves_like :array_pack_numeric_basic, 'e'
|
||||
it_behaves_like :array_pack_float, 'e'
|
||||
it_behaves_like :array_pack_float_le, 'e'
|
||||
end
|
11
spec/ruby/core/array/pack/empty_spec.rb
Normal file
11
spec/ruby/core/array/pack/empty_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#pack with empty format" do
|
||||
it "returns an empty String" do
|
||||
[1, 2, 3].pack("").should == ""
|
||||
end
|
||||
|
||||
it "returns a String with US-ASCII encoding" do
|
||||
[1, 2, 3].pack("").encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
end
|
39
spec/ruby/core/array/pack/f_spec.rb
Normal file
39
spec/ruby/core/array/pack/f_spec.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/float', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'F'" do
|
||||
it_behaves_like :array_pack_basic, 'F'
|
||||
it_behaves_like :array_pack_basic_float, 'F'
|
||||
it_behaves_like :array_pack_arguments, 'F'
|
||||
it_behaves_like :array_pack_no_platform, 'F'
|
||||
it_behaves_like :array_pack_numeric_basic, 'F'
|
||||
it_behaves_like :array_pack_float, 'F'
|
||||
|
||||
little_endian do
|
||||
it_behaves_like :array_pack_float_le, 'F'
|
||||
end
|
||||
|
||||
big_endian do
|
||||
it_behaves_like :array_pack_float_be, 'F'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'f'" do
|
||||
it_behaves_like :array_pack_basic, 'f'
|
||||
it_behaves_like :array_pack_basic_float, 'f'
|
||||
it_behaves_like :array_pack_arguments, 'f'
|
||||
it_behaves_like :array_pack_no_platform, 'f'
|
||||
it_behaves_like :array_pack_numeric_basic, 'f'
|
||||
it_behaves_like :array_pack_float, 'f'
|
||||
|
||||
little_endian do
|
||||
it_behaves_like :array_pack_float_le, 'f'
|
||||
end
|
||||
|
||||
big_endian do
|
||||
it_behaves_like :array_pack_float_be, 'f'
|
||||
end
|
||||
end
|
25
spec/ruby/core/array/pack/g_spec.rb
Normal file
25
spec/ruby/core/array/pack/g_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/float', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'G'" do
|
||||
it_behaves_like :array_pack_basic, 'G'
|
||||
it_behaves_like :array_pack_basic_float, 'G'
|
||||
it_behaves_like :array_pack_arguments, 'G'
|
||||
it_behaves_like :array_pack_no_platform, 'G'
|
||||
it_behaves_like :array_pack_numeric_basic, 'G'
|
||||
it_behaves_like :array_pack_float, 'G'
|
||||
it_behaves_like :array_pack_double_be, 'G'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'g'" do
|
||||
it_behaves_like :array_pack_basic, 'g'
|
||||
it_behaves_like :array_pack_basic_float, 'g'
|
||||
it_behaves_like :array_pack_arguments, 'g'
|
||||
it_behaves_like :array_pack_no_platform, 'g'
|
||||
it_behaves_like :array_pack_numeric_basic, 'g'
|
||||
it_behaves_like :array_pack_float, 'g'
|
||||
it_behaves_like :array_pack_float_be, 'g'
|
||||
end
|
197
spec/ruby/core/array/pack/h_spec.rb
Normal file
197
spec/ruby/core/array/pack/h_spec.rb
Normal file
|
@ -0,0 +1,197 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/encodings', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'H'" do
|
||||
it_behaves_like :array_pack_basic, 'H'
|
||||
it_behaves_like :array_pack_basic_non_float, 'H'
|
||||
it_behaves_like :array_pack_arguments, 'H'
|
||||
it_behaves_like :array_pack_hex, 'H'
|
||||
|
||||
it "calls #to_str to convert an Object to a String" do
|
||||
obj = mock("pack H string")
|
||||
obj.should_receive(:to_str).and_return("a")
|
||||
[obj].pack("H").should == "\xa0"
|
||||
end
|
||||
|
||||
it "encodes the first character as the most significant nibble when passed no count modifier" do
|
||||
["ab"].pack("H").should == "\xa0"
|
||||
end
|
||||
|
||||
it "implicitly has count equal to the string length when passed the '*' modifier" do
|
||||
["deadbeef"].pack("H*").should == "\xde\xad\xbe\xef"
|
||||
end
|
||||
|
||||
it "encodes count nibbles when passed a count modifier exceeding the string length" do
|
||||
["ab"].pack('H8').should == "\xab\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "encodes the first character as the most significant nibble of a hex value" do
|
||||
[ [["0"], "\x00"],
|
||||
[["1"], "\x10"],
|
||||
[["2"], "\x20"],
|
||||
[["3"], "\x30"],
|
||||
[["4"], "\x40"],
|
||||
[["5"], "\x50"],
|
||||
[["6"], "\x60"],
|
||||
[["7"], "\x70"],
|
||||
[["8"], "\x80"],
|
||||
[["9"], "\x90"],
|
||||
[["a"], "\xa0"],
|
||||
[["b"], "\xb0"],
|
||||
[["c"], "\xc0"],
|
||||
[["d"], "\xd0"],
|
||||
[["e"], "\xe0"],
|
||||
[["f"], "\xf0"],
|
||||
[["A"], "\xa0"],
|
||||
[["B"], "\xb0"],
|
||||
[["C"], "\xc0"],
|
||||
[["D"], "\xd0"],
|
||||
[["E"], "\xe0"],
|
||||
[["F"], "\xf0"]
|
||||
].should be_computed_by(:pack, "H")
|
||||
end
|
||||
|
||||
it "encodes the second character as the least significant nibble of a hex value" do
|
||||
[ [["00"], "\x00"],
|
||||
[["01"], "\x01"],
|
||||
[["02"], "\x02"],
|
||||
[["03"], "\x03"],
|
||||
[["04"], "\x04"],
|
||||
[["05"], "\x05"],
|
||||
[["06"], "\x06"],
|
||||
[["07"], "\x07"],
|
||||
[["08"], "\x08"],
|
||||
[["09"], "\x09"],
|
||||
[["0a"], "\x0a"],
|
||||
[["0b"], "\x0b"],
|
||||
[["0c"], "\x0c"],
|
||||
[["0d"], "\x0d"],
|
||||
[["0e"], "\x0e"],
|
||||
[["0f"], "\x0f"],
|
||||
[["0A"], "\x0a"],
|
||||
[["0B"], "\x0b"],
|
||||
[["0C"], "\x0c"],
|
||||
[["0D"], "\x0d"],
|
||||
[["0E"], "\x0e"],
|
||||
[["0F"], "\x0f"]
|
||||
].should be_computed_by(:pack, "H2")
|
||||
end
|
||||
|
||||
it "encodes the least significant nibble of a non alphanumeric character as the most significant nibble of the hex value" do
|
||||
[ [["^"], "\xe0"],
|
||||
[["*"], "\xa0"],
|
||||
[["#"], "\x30"],
|
||||
[["["], "\xb0"],
|
||||
[["]"], "\xd0"],
|
||||
[["@"], "\x00"],
|
||||
[["!"], "\x10"],
|
||||
[["H"], "\x10"],
|
||||
[["O"], "\x80"],
|
||||
[["T"], "\xd0"],
|
||||
[["Z"], "\x30"],
|
||||
].should be_computed_by(:pack, "H")
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
["41"].pack("H").encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'h'" do
|
||||
it_behaves_like :array_pack_basic, 'h'
|
||||
it_behaves_like :array_pack_basic_non_float, 'h'
|
||||
it_behaves_like :array_pack_arguments, 'h'
|
||||
it_behaves_like :array_pack_hex, 'h'
|
||||
|
||||
it "calls #to_str to convert an Object to a String" do
|
||||
obj = mock("pack H string")
|
||||
obj.should_receive(:to_str).and_return("a")
|
||||
[obj].pack("h").should == "\x0a"
|
||||
end
|
||||
|
||||
it "encodes the first character as the least significant nibble when passed no count modifier" do
|
||||
["ab"].pack("h").should == "\x0a"
|
||||
end
|
||||
|
||||
it "implicitly has count equal to the string length when passed the '*' modifier" do
|
||||
["deadbeef"].pack("h*").should == "\xed\xda\xeb\xfe"
|
||||
end
|
||||
|
||||
it "encodes count nibbles when passed a count modifier exceeding the string length" do
|
||||
["ab"].pack('h8').should == "\xba\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "encodes the first character as the least significant nibble of a hex value" do
|
||||
[ [["0"], "\x00"],
|
||||
[["1"], "\x01"],
|
||||
[["2"], "\x02"],
|
||||
[["3"], "\x03"],
|
||||
[["4"], "\x04"],
|
||||
[["5"], "\x05"],
|
||||
[["6"], "\x06"],
|
||||
[["7"], "\x07"],
|
||||
[["8"], "\x08"],
|
||||
[["9"], "\x09"],
|
||||
[["a"], "\x0a"],
|
||||
[["b"], "\x0b"],
|
||||
[["c"], "\x0c"],
|
||||
[["d"], "\x0d"],
|
||||
[["e"], "\x0e"],
|
||||
[["f"], "\x0f"],
|
||||
[["A"], "\x0a"],
|
||||
[["B"], "\x0b"],
|
||||
[["C"], "\x0c"],
|
||||
[["D"], "\x0d"],
|
||||
[["E"], "\x0e"],
|
||||
[["F"], "\x0f"]
|
||||
].should be_computed_by(:pack, "h")
|
||||
end
|
||||
|
||||
it "encodes the second character as the most significant nibble of a hex value" do
|
||||
[ [["00"], "\x00"],
|
||||
[["01"], "\x10"],
|
||||
[["02"], "\x20"],
|
||||
[["03"], "\x30"],
|
||||
[["04"], "\x40"],
|
||||
[["05"], "\x50"],
|
||||
[["06"], "\x60"],
|
||||
[["07"], "\x70"],
|
||||
[["08"], "\x80"],
|
||||
[["09"], "\x90"],
|
||||
[["0a"], "\xa0"],
|
||||
[["0b"], "\xb0"],
|
||||
[["0c"], "\xc0"],
|
||||
[["0d"], "\xd0"],
|
||||
[["0e"], "\xe0"],
|
||||
[["0f"], "\xf0"],
|
||||
[["0A"], "\xa0"],
|
||||
[["0B"], "\xb0"],
|
||||
[["0C"], "\xc0"],
|
||||
[["0D"], "\xd0"],
|
||||
[["0E"], "\xe0"],
|
||||
[["0F"], "\xf0"]
|
||||
].should be_computed_by(:pack, "h2")
|
||||
end
|
||||
|
||||
it "encodes the least significant nibble of a non alphanumeric character as the least significant nibble of the hex value" do
|
||||
[ [["^"], "\x0e"],
|
||||
[["*"], "\x0a"],
|
||||
[["#"], "\x03"],
|
||||
[["["], "\x0b"],
|
||||
[["]"], "\x0d"],
|
||||
[["@"], "\x00"],
|
||||
[["!"], "\x01"],
|
||||
[["H"], "\x01"],
|
||||
[["O"], "\x08"],
|
||||
[["T"], "\x0d"],
|
||||
[["Z"], "\x03"],
|
||||
].should be_computed_by(:pack, "h")
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
["41"].pack("h").encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
end
|
133
spec/ruby/core/array/pack/i_spec.rb
Normal file
133
spec/ruby/core/array/pack/i_spec.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'I'" do
|
||||
it_behaves_like :array_pack_basic, 'I'
|
||||
it_behaves_like :array_pack_basic_non_float, 'I'
|
||||
it_behaves_like :array_pack_arguments, 'I'
|
||||
it_behaves_like :array_pack_numeric_basic, 'I'
|
||||
it_behaves_like :array_pack_integer, 'I'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i'" do
|
||||
it_behaves_like :array_pack_basic, 'i'
|
||||
it_behaves_like :array_pack_basic_non_float, 'i'
|
||||
it_behaves_like :array_pack_arguments, 'i'
|
||||
it_behaves_like :array_pack_numeric_basic, 'i'
|
||||
it_behaves_like :array_pack_integer, 'i'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'I'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'I<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'I<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'I_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'I<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'I!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'I>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'I>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'I_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'I>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'I!>'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'i<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'i<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'i_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'i<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'i!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'i>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'i>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'i_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'i>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'i!>'
|
||||
end
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'I'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'I'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'I' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le_platform, 'I_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'I' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le_platform, 'I!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'i'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le_platform, 'i_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le_platform, 'i!'
|
||||
end
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'I'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'I'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'I' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be_platform, 'I_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'I' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be_platform, 'I!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'i'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be_platform, 'i_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'i' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be_platform, 'i!'
|
||||
end
|
||||
end
|
222
spec/ruby/core/array/pack/j_spec.rb
Normal file
222
spec/ruby/core/array/pack/j_spec.rb
Normal file
|
@ -0,0 +1,222 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
ruby_version_is '2.3' do
|
||||
# To handle the special case of x64-mingw32
|
||||
pointer_size = RUBY_PLATFORM =~ /\bx64\b/ ? 64 : 1.size * 8
|
||||
|
||||
guard -> { pointer_size == 64 } do
|
||||
describe "Array#pack with format 'J'" do
|
||||
it_behaves_like :array_pack_basic, 'J'
|
||||
it_behaves_like :array_pack_basic_non_float, 'J'
|
||||
it_behaves_like :array_pack_arguments, 'J'
|
||||
it_behaves_like :array_pack_numeric_basic, 'J'
|
||||
it_behaves_like :array_pack_integer, 'J'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
it_behaves_like :array_pack_basic, 'j'
|
||||
it_behaves_like :array_pack_basic_non_float, 'j'
|
||||
it_behaves_like :array_pack_arguments, 'j'
|
||||
it_behaves_like :array_pack_numeric_basic, 'j'
|
||||
it_behaves_like :array_pack_integer, 'j'
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'J_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'J!'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'j_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'j!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'J_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'J!'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'j_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'j!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'J<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'J_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'J<!'
|
||||
it_behaves_like :array_pack_64bit_le, 'J!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'J>_'
|
||||
it_behaves_like :array_pack_64bit_be, 'J_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'J>!'
|
||||
it_behaves_like :array_pack_64bit_be, 'J!>'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'j<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'j_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'j<!'
|
||||
it_behaves_like :array_pack_64bit_le, 'j!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'j>_'
|
||||
it_behaves_like :array_pack_64bit_be, 'j_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'j>!'
|
||||
it_behaves_like :array_pack_64bit_be, 'j!>'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { pointer_size == 32 } do
|
||||
describe "Array#pack with format 'J'" do
|
||||
it_behaves_like :array_pack_basic, 'J'
|
||||
it_behaves_like :array_pack_basic_non_float, 'J'
|
||||
it_behaves_like :array_pack_arguments, 'J'
|
||||
it_behaves_like :array_pack_numeric_basic, 'J'
|
||||
it_behaves_like :array_pack_integer, 'J'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
it_behaves_like :array_pack_basic, 'j'
|
||||
it_behaves_like :array_pack_basic_non_float, 'j'
|
||||
it_behaves_like :array_pack_arguments, 'j'
|
||||
it_behaves_like :array_pack_numeric_basic, 'j'
|
||||
it_behaves_like :array_pack_integer, 'j'
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'J_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'J!'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'j_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'j!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'J_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'J!'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'j_'
|
||||
end
|
||||
|
||||
describe "with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'j!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'J'" do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'J<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'J_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'J<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'J!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'J>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'J_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'J>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'J!>'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'j'" do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'j<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'j_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'j<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'j!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'j>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'j_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'j>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'j!>'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
221
spec/ruby/core/array/pack/l_spec.rb
Normal file
221
spec/ruby/core/array/pack/l_spec.rb
Normal file
|
@ -0,0 +1,221 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'L'" do
|
||||
it_behaves_like :array_pack_basic, 'L'
|
||||
it_behaves_like :array_pack_basic_non_float, 'L'
|
||||
it_behaves_like :array_pack_arguments, 'L'
|
||||
it_behaves_like :array_pack_numeric_basic, 'L'
|
||||
it_behaves_like :array_pack_integer, 'L'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l'" do
|
||||
it_behaves_like :array_pack_basic, 'l'
|
||||
it_behaves_like :array_pack_basic_non_float, 'l'
|
||||
it_behaves_like :array_pack_arguments, 'l'
|
||||
it_behaves_like :array_pack_numeric_basic, 'l'
|
||||
it_behaves_like :array_pack_integer, 'l'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'L'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L>'
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'L_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'L!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'L_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'L!>'
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'L_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L<!'
|
||||
it_behaves_like :array_pack_64bit_le, 'L!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'L>_'
|
||||
it_behaves_like :array_pack_64bit_be, 'L_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'L>!'
|
||||
it_behaves_like :array_pack_64bit_be, 'L!>'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l>'
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'l_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l<!'
|
||||
it_behaves_like :array_pack_32bit_le, 'l!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l>_'
|
||||
it_behaves_like :array_pack_32bit_be, 'l_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l>!'
|
||||
it_behaves_like :array_pack_32bit_be, 'l!>'
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'l<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'l_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'l<!'
|
||||
it_behaves_like :array_pack_64bit_le, 'l!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'l>_'
|
||||
it_behaves_like :array_pack_64bit_be, 'l_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'l>!'
|
||||
it_behaves_like :array_pack_64bit_be, 'l!>'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'L'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l'
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'L' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l!'
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'L' with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'l_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'l!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'L'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l'
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'L' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '!'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'l!'
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'L_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'L' with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'L!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'l_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'l' with modifier '!'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'l!'
|
||||
end
|
||||
end
|
||||
end
|
306
spec/ruby/core/array/pack/m_spec.rb
Normal file
306
spec/ruby/core/array/pack/m_spec.rb
Normal file
|
@ -0,0 +1,306 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'M'" do
|
||||
it_behaves_like :array_pack_basic, 'M'
|
||||
it_behaves_like :array_pack_basic_non_float, 'M'
|
||||
it_behaves_like :array_pack_arguments, 'M'
|
||||
|
||||
it "encodes an empty string as an empty string" do
|
||||
[""].pack("M").should == ""
|
||||
end
|
||||
|
||||
it "encodes nil as an empty string" do
|
||||
[nil].pack("M").should == ""
|
||||
end
|
||||
|
||||
it "appends a soft line break at the end of an encoded string" do
|
||||
["a"].pack("M").should == "a=\n"
|
||||
end
|
||||
|
||||
it "does not append a soft break if the string ends with a newline" do
|
||||
["a\n"].pack("M").should == "a\n"
|
||||
end
|
||||
|
||||
it "encodes one element for each directive" do
|
||||
["a", "b", "c"].pack("MM").should == "a=\nb=\n"
|
||||
end
|
||||
|
||||
it "encodes byte values 33..60 directly" do
|
||||
[ [["!\"\#$%&'()*+,-./"], "!\"\#$%&'()*+,-./=\n"],
|
||||
[["0123456789"], "0123456789=\n"],
|
||||
[[":;<"], ":;<=\n"]
|
||||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "encodes byte values 62..126 directly" do
|
||||
[ [[">?@"], ">?@=\n"],
|
||||
[["ABCDEFGHIJKLMNOPQRSTUVWXYZ"], "ABCDEFGHIJKLMNOPQRSTUVWXYZ=\n"],
|
||||
[["[\\]^_`"], "[\\]^_`=\n"],
|
||||
[["abcdefghijklmnopqrstuvwxyz"], "abcdefghijklmnopqrstuvwxyz=\n"],
|
||||
[["{|}~"], "{|}~=\n"]
|
||||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "encodes an '=' character in hex format" do
|
||||
["="].pack("M").should == "=3D=\n"
|
||||
end
|
||||
|
||||
it "encodes an embedded space directly" do
|
||||
["a b"].pack("M").should == "a b=\n"
|
||||
end
|
||||
|
||||
it "encodes a space at the end of the string directly" do
|
||||
["a "].pack("M").should == "a =\n"
|
||||
end
|
||||
|
||||
it "encodes an embedded tab directly" do
|
||||
["a\tb"].pack("M").should == "a\tb=\n"
|
||||
end
|
||||
|
||||
it "encodes a tab at the end of the string directly" do
|
||||
["a\t"].pack("M").should == "a\t=\n"
|
||||
end
|
||||
|
||||
it "encodes an embedded newline directly" do
|
||||
["a\nb"].pack("M").should == "a\nb=\n"
|
||||
end
|
||||
|
||||
it "encodes 0..31 except tab and newline in hex format" do
|
||||
[ [["\x00\x01\x02\x03\x04\x05\x06"], "=00=01=02=03=04=05=06=\n"],
|
||||
[["\a\b\v\f\r"], "=07=08=0B=0C=0D=\n"],
|
||||
[["\x0e\x0f\x10\x11\x12\x13\x14"], "=0E=0F=10=11=12=13=14=\n"],
|
||||
[["\x15\x16\x17\x18\x19\x1a"], "=15=16=17=18=19=1A=\n"],
|
||||
[["\e"], "=1B=\n"],
|
||||
[["\x1c\x1d\x1e\x1f"], "=1C=1D=1E=1F=\n"]
|
||||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "encodes a tab followed by a newline with an encoded newline" do
|
||||
["\t\n"].pack("M").should == "\t=\n\n"
|
||||
end
|
||||
|
||||
it "encodes 127..255 in hex format" do
|
||||
[ [["\x7f\x80\x81\x82\x83\x84\x85\x86"], "=7F=80=81=82=83=84=85=86=\n"],
|
||||
[["\x87\x88\x89\x8a\x8b\x8c\x8d\x8e"], "=87=88=89=8A=8B=8C=8D=8E=\n"],
|
||||
[["\x8f\x90\x91\x92\x93\x94\x95\x96"], "=8F=90=91=92=93=94=95=96=\n"],
|
||||
[["\x97\x98\x99\x9a\x9b\x9c\x9d\x9e"], "=97=98=99=9A=9B=9C=9D=9E=\n"],
|
||||
[["\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6"], "=9F=A0=A1=A2=A3=A4=A5=A6=\n"],
|
||||
[["\xa7\xa8\xa9\xaa\xab\xac\xad\xae"], "=A7=A8=A9=AA=AB=AC=AD=AE=\n"],
|
||||
[["\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6"], "=AF=B0=B1=B2=B3=B4=B5=B6=\n"],
|
||||
[["\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe"], "=B7=B8=B9=BA=BB=BC=BD=BE=\n"],
|
||||
[["\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"], "=BF=C0=C1=C2=C3=C4=C5=C6=\n"],
|
||||
[["\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce"], "=C7=C8=C9=CA=CB=CC=CD=CE=\n"],
|
||||
[["\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6"], "=CF=D0=D1=D2=D3=D4=D5=D6=\n"],
|
||||
[["\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde"], "=D7=D8=D9=DA=DB=DC=DD=DE=\n"],
|
||||
[["\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6"], "=DF=E0=E1=E2=E3=E4=E5=E6=\n"],
|
||||
[["\xe7\xe8\xe9\xea\xeb\xec\xed\xee"], "=E7=E8=E9=EA=EB=EC=ED=EE=\n"],
|
||||
[["\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6"], "=EF=F0=F1=F2=F3=F4=F5=F6=\n"],
|
||||
[["\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"], "=F7=F8=F9=FA=FB=FC=FD=FE=\n"],
|
||||
[["\xff"], "=FF=\n"]
|
||||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "emits a soft line break when the output exceeds 72 characters when passed '*', 0, 1, or no count modifier" do
|
||||
s1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
r1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\na=\n"
|
||||
s2 = "\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19"
|
||||
r2 = "=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=19=\n=19=\n"
|
||||
s3 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x15a"
|
||||
r3 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=15=\na=\n"
|
||||
s4 = "\x15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x15a"
|
||||
r4 = "=15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\na=15a=\n"
|
||||
|
||||
[ [[s1], "M", r1],
|
||||
[[s1], "M0", r1],
|
||||
[[s1], "M1", r1],
|
||||
[[s2], "M", r2],
|
||||
[[s2], "M0", r2],
|
||||
[[s2], "M1", r2],
|
||||
[[s3], "M", r3],
|
||||
[[s3], "M0", r3],
|
||||
[[s3], "M1", r3],
|
||||
[[s4], "M", r4],
|
||||
[[s4], "M0", r4],
|
||||
[[s4], "M1", r4]
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "emits a soft line break when the output exceeds count characters" do
|
||||
[ [["abcdefghi"], "M2", "abc=\ndef=\nghi=\n"],
|
||||
[["abcdefghi"], "M3", "abcd=\nefgh=\ni=\n"],
|
||||
[["abcdefghi"], "M4", "abcde=\nfghi=\n"],
|
||||
[["abcdefghi"], "M5", "abcdef=\nghi=\n"],
|
||||
[["abcdefghi"], "M6", "abcdefg=\nhi=\n"],
|
||||
[["\x19\x19\x19\x19"], "M2", "=19=\n=19=\n=19=\n=19=\n"],
|
||||
[["\x19\x19\x19\x19"], "M3", "=19=19=\n=19=19=\n"],
|
||||
[["\x19\x19\x19\x19"], "M4", "=19=19=\n=19=19=\n"],
|
||||
[["\x19\x19\x19\x19"], "M5", "=19=19=\n=19=19=\n"],
|
||||
[["\x19\x19\x19\x19"], "M6", "=19=19=19=\n=19=\n"],
|
||||
[["\x19\x19\x19\x19"], "M7", "=19=19=19=\n=19=\n"]
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "encodes a recursive array" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.pack('M').should be_an_instance_of(String)
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.pack('M').should == "1=\n"
|
||||
end
|
||||
|
||||
it "calls #to_s to convert an object to a String" do
|
||||
obj = mock("pack M string")
|
||||
obj.should_receive(:to_s).and_return("packing")
|
||||
|
||||
[obj].pack("M").should == "packing=\n"
|
||||
end
|
||||
|
||||
it "converts the object to a String representation if #to_s does not return a String" do
|
||||
obj = mock("pack M non-string")
|
||||
obj.should_receive(:to_s).and_return(2)
|
||||
|
||||
[obj].pack("M").should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "encodes a Symbol as a String" do
|
||||
[:symbol].pack("M").should == "symbol=\n"
|
||||
end
|
||||
|
||||
it "encodes an Integer as a String" do
|
||||
[ [[1], "1=\n"],
|
||||
[[bignum_value], "#{bignum_value}=\n"]
|
||||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "encodes a Float as a String" do
|
||||
[1.0].pack("M").should == "1.0=\n"
|
||||
end
|
||||
|
||||
it "converts Floats to the minimum unique representation" do
|
||||
[1.0 / 3.0].pack("M").should == "0.3333333333333333=\n"
|
||||
end
|
||||
|
||||
it "sets the output string to US-ASCII encoding" do
|
||||
["abcd"].pack("M").encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'm'" do
|
||||
it_behaves_like :array_pack_basic, 'm'
|
||||
it_behaves_like :array_pack_basic_non_float, 'm'
|
||||
it_behaves_like :array_pack_arguments, 'm'
|
||||
|
||||
it "encodes an empty string as an empty string" do
|
||||
[""].pack("m").should == ""
|
||||
end
|
||||
|
||||
it "appends a newline to the end of the encoded string" do
|
||||
["a"].pack("m").should == "YQ==\n"
|
||||
end
|
||||
|
||||
it "encodes one element per directive" do
|
||||
["abc", "DEF"].pack("mm").should == "YWJj\nREVG\n"
|
||||
end
|
||||
|
||||
it "encodes 1, 2, or 3 characters in 4 output characters (Base64 encoding)" do
|
||||
[ [["a"], "YQ==\n"],
|
||||
[["ab"], "YWI=\n"],
|
||||
[["abc"], "YWJj\n"],
|
||||
[["abcd"], "YWJjZA==\n"],
|
||||
[["abcde"], "YWJjZGU=\n"],
|
||||
[["abcdef"], "YWJjZGVm\n"],
|
||||
[["abcdefg"], "YWJjZGVmZw==\n"],
|
||||
].should be_computed_by(:pack, "m")
|
||||
end
|
||||
|
||||
it "emits a newline after complete groups of count / 3 input characters when passed a count modifier" do
|
||||
["abcdefg"].pack("m3").should == "YWJj\nZGVm\nZw==\n"
|
||||
end
|
||||
|
||||
it "implicitly has a count of 45 when passed '*', 1, 2 or no count modifier" do
|
||||
s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
r = "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\nYWFhYWE=\n"
|
||||
[ [[s], "m", r],
|
||||
[[s], "m*", r],
|
||||
[[s], "m1", r],
|
||||
[[s], "m2", r],
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "encodes all ascii characters" do
|
||||
[ [["\x00\x01\x02\x03\x04\x05\x06"], "AAECAwQFBg==\n"],
|
||||
[["\a\b\t\n\v\f\r"], "BwgJCgsMDQ==\n"],
|
||||
[["\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"], "Dg8QERITFBUW\n"],
|
||||
[["\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f"], "FxgZGhscHR4f\n"],
|
||||
[["!\"\#$%&'()*+,-./"], "ISIjJCUmJygpKissLS4v\n"],
|
||||
[["0123456789"], "MDEyMzQ1Njc4OQ==\n"],
|
||||
[[":;<=>?@"], "Ojs8PT4/QA==\n"],
|
||||
[["ABCDEFGHIJKLMNOPQRSTUVWXYZ"], "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=\n"],
|
||||
[["[\\]^_`"], "W1xdXl9g\n"],
|
||||
[["abcdefghijklmnopqrstuvwxyz"], "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=\n"],
|
||||
[["{|}~"], "e3x9fg==\n"],
|
||||
[["\x7f\xc2\x80\xc2\x81\xc2\x82\xc2\x83"], "f8KAwoHCgsKD\n"],
|
||||
[["\xc2\x84\xc2\x85\xc2\x86\xc2\x87\xc2"], "woTChcKGwofC\n"],
|
||||
[["\x88\xc2\x89\xc2\x8a\xc2\x8b\xc2\x8c"], "iMKJworCi8KM\n"],
|
||||
[["\xc2\x8d\xc2\x8e\xc2\x8f\xc2\x90\xc2"], "wo3CjsKPwpDC\n"],
|
||||
[["\x91\xc2\x92\xc2\x93\xc2\x94\xc2\x95"], "kcKSwpPClMKV\n"],
|
||||
[["\xc2\x96\xc2\x97\xc2\x98\xc2\x99\xc2"], "wpbCl8KYwpnC\n"],
|
||||
[["\x9a\xc2\x9b\xc2\x9c\xc2\x9d\xc2\x9e"], "msKbwpzCncKe\n"],
|
||||
[["\xc2\x9f\xc2\xa0\xc2\xa1\xc2\xa2\xc2"], "wp/CoMKhwqLC\n"],
|
||||
[["\xa3\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa7"], "o8KkwqXCpsKn\n"],
|
||||
[["\xc2\xa8\xc2\xa9\xc2\xaa\xc2\xab\xc2"], "wqjCqcKqwqvC\n"],
|
||||
[["\xac\xc2\xad\xc2\xae\xc2\xaf\xc2\xb0"], "rMKtwq7Cr8Kw\n"],
|
||||
[["\xc2\xb1\xc2\xb2\xc2\xb3\xc2\xb4\xc2"], "wrHCssKzwrTC\n"],
|
||||
[["\xb5\xc2\xb6\xc2\xb7\xc2\xb8\xc2\xb9"], "tcK2wrfCuMK5\n"],
|
||||
[["\xc2\xba\xc2\xbb\xc2\xbc\xc2\xbd\xc2"], "wrrCu8K8wr3C\n"],
|
||||
[["\xbe\xc2\xbf\xc3\x80\xc3\x81\xc3\x82"], "vsK/w4DDgcOC\n"],
|
||||
[["\xc3\x83\xc3\x84\xc3\x85\xc3\x86\xc3"], "w4PDhMOFw4bD\n"],
|
||||
[["\x87\xc3\x88\xc3\x89\xc3\x8a\xc3\x8b"], "h8OIw4nDisOL\n"],
|
||||
[["\xc3\x8c\xc3\x8d\xc3\x8e\xc3\x8f\xc3"], "w4zDjcOOw4/D\n"],
|
||||
[["\x90\xc3\x91\xc3\x92\xc3\x93\xc3\x94"], "kMORw5LDk8OU\n"],
|
||||
[["\xc3\x95\xc3\x96\xc3\x97\xc3\x98\xc3"], "w5XDlsOXw5jD\n"],
|
||||
[["\x99\xc3\x9a\xc3\x9b\xc3\x9c\xc3\x9d"], "mcOaw5vDnMOd\n"],
|
||||
[["\xc3\x9e\xc3\x9f\xc3\xa0\xc3\xa1\xc3"], "w57Dn8Ogw6HD\n"],
|
||||
[["\xa2\xc3\xa3\xc3\xa4\xc3\xa5\xc3\xa6"], "osOjw6TDpcOm\n"],
|
||||
[["\xc3\xa7\xc3\xa8\xc3\xa9\xc3\xaa\xc3"], "w6fDqMOpw6rD\n"],
|
||||
[["\xab\xc3\xac\xc3\xad\xc3\xae\xc3\xaf"], "q8Osw63DrsOv\n"],
|
||||
[["\xc3\xb0\xc3\xb1\xc3\xb2\xc3\xb3\xc3"], "w7DDscOyw7PD\n"],
|
||||
[["\xb4\xc3\xb5\xc3\xb6\xc3\xb7\xc3\xb8"], "tMO1w7bDt8O4\n"],
|
||||
[["\xc3\xb9\xc3\xba\xc3\xbb\xc3\xbc\xc3"], "w7nDusO7w7zD\n"],
|
||||
[["\xbd\xc3\xbe\xc3\xbf"], "vcO+w78=\n"]
|
||||
].should be_computed_by(:pack, "m")
|
||||
end
|
||||
|
||||
it "calls #to_str to convert an object to a String" do
|
||||
obj = mock("pack m string")
|
||||
obj.should_receive(:to_str).and_return("abc")
|
||||
[obj].pack("m").should == "YWJj\n"
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_str does not return a String" do
|
||||
obj = mock("pack m non-string")
|
||||
lambda { [obj].pack("m") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed nil" do
|
||||
lambda { [nil].pack("m") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed an Integer" do
|
||||
lambda { [0].pack("m") }.should raise_error(TypeError)
|
||||
lambda { [bignum_value].pack("m") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not emit a newline if passed zero as the count modifier" do
|
||||
s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
r = "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE="
|
||||
[s].pack("m0").should == r
|
||||
end
|
||||
|
||||
it "sets the output string to US-ASCII encoding" do
|
||||
["abcd"].pack("m").encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
end
|
25
spec/ruby/core/array/pack/n_spec.rb
Normal file
25
spec/ruby/core/array/pack/n_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'N'" do
|
||||
it_behaves_like :array_pack_basic, 'N'
|
||||
it_behaves_like :array_pack_basic_non_float, 'N'
|
||||
it_behaves_like :array_pack_arguments, 'N'
|
||||
it_behaves_like :array_pack_numeric_basic, 'N'
|
||||
it_behaves_like :array_pack_integer, 'N'
|
||||
it_behaves_like :array_pack_no_platform, 'N'
|
||||
it_behaves_like :array_pack_32bit_be, 'N'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'n'" do
|
||||
it_behaves_like :array_pack_basic, 'n'
|
||||
it_behaves_like :array_pack_basic_non_float, 'n'
|
||||
it_behaves_like :array_pack_arguments, 'n'
|
||||
it_behaves_like :array_pack_numeric_basic, 'n'
|
||||
it_behaves_like :array_pack_integer, 'n'
|
||||
it_behaves_like :array_pack_no_platform, 'n'
|
||||
it_behaves_like :array_pack_16bit_be, 'n'
|
||||
end
|
11
spec/ruby/core/array/pack/p_spec.rb
Normal file
11
spec/ruby/core/array/pack/p_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'P'" do
|
||||
it_behaves_like :array_pack_basic_non_float, 'P'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'p'" do
|
||||
it_behaves_like :array_pack_basic_non_float, 'p'
|
||||
end
|
7
spec/ruby/core/array/pack/percent_spec.rb
Normal file
7
spec/ruby/core/array/pack/percent_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#pack with format '%'" do
|
||||
it "raises an Argument Error" do
|
||||
lambda { [1].pack("%") }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
61
spec/ruby/core/array/pack/q_spec.rb
Normal file
61
spec/ruby/core/array/pack/q_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'Q'" do
|
||||
it_behaves_like :array_pack_basic, 'Q'
|
||||
it_behaves_like :array_pack_basic_non_float, 'Q'
|
||||
it_behaves_like :array_pack_arguments, 'Q'
|
||||
it_behaves_like :array_pack_numeric_basic, 'Q'
|
||||
it_behaves_like :array_pack_integer, 'Q'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'q'" do
|
||||
it_behaves_like :array_pack_basic, 'q'
|
||||
it_behaves_like :array_pack_basic_non_float, 'q'
|
||||
it_behaves_like :array_pack_arguments, 'q'
|
||||
it_behaves_like :array_pack_numeric_basic, 'q'
|
||||
it_behaves_like :array_pack_integer, 'q'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'Q'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'Q<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'Q>'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'q'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'q<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'q>'
|
||||
end
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'Q'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'Q'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'q'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'q'
|
||||
end
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'Q'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'Q'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'q'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'q'
|
||||
end
|
||||
end
|
133
spec/ruby/core/array/pack/s_spec.rb
Normal file
133
spec/ruby/core/array/pack/s_spec.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'S'" do
|
||||
it_behaves_like :array_pack_basic, 'S'
|
||||
it_behaves_like :array_pack_basic_non_float, 'S'
|
||||
it_behaves_like :array_pack_arguments, 'S'
|
||||
it_behaves_like :array_pack_numeric_basic, 'S'
|
||||
it_behaves_like :array_pack_integer, 'S'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's'" do
|
||||
it_behaves_like :array_pack_basic, 's'
|
||||
it_behaves_like :array_pack_basic_non_float, 's'
|
||||
it_behaves_like :array_pack_arguments, 's'
|
||||
it_behaves_like :array_pack_numeric_basic, 's'
|
||||
it_behaves_like :array_pack_integer, 's'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'S'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S<_'
|
||||
it_behaves_like :array_pack_16bit_le, 'S_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S<!'
|
||||
it_behaves_like :array_pack_16bit_le, 'S!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S>_'
|
||||
it_behaves_like :array_pack_16bit_be, 'S_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S>!'
|
||||
it_behaves_like :array_pack_16bit_be, 'S!>'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's'" do
|
||||
describe "with modifier '<'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's<_'
|
||||
it_behaves_like :array_pack_16bit_le, 's_<'
|
||||
end
|
||||
|
||||
describe "with modifier '<' and '!'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's<!'
|
||||
it_behaves_like :array_pack_16bit_le, 's!<'
|
||||
end
|
||||
|
||||
describe "with modifier '>'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '_'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's>_'
|
||||
it_behaves_like :array_pack_16bit_be, 's_>'
|
||||
end
|
||||
|
||||
describe "with modifier '>' and '!'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's>!'
|
||||
it_behaves_like :array_pack_16bit_be, 's!>'
|
||||
end
|
||||
end
|
||||
|
||||
little_endian do
|
||||
describe "Array#pack with format 'S'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'S' with modifier '_'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'S' with modifier '!'" do
|
||||
it_behaves_like :array_pack_16bit_le, 'S!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's' with modifier '_'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's' with modifier '!'" do
|
||||
it_behaves_like :array_pack_16bit_le, 's!'
|
||||
end
|
||||
end
|
||||
|
||||
big_endian do
|
||||
describe "Array#pack with format 'S'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'S' with modifier '_'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'S' with modifier '!'" do
|
||||
it_behaves_like :array_pack_16bit_be, 'S!'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's' with modifier '_'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's_'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 's' with modifier '!'" do
|
||||
it_behaves_like :array_pack_16bit_be, 's!'
|
||||
end
|
||||
end
|
65
spec/ruby/core/array/pack/shared/basic.rb
Normal file
65
spec/ruby/core/array/pack/shared/basic.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
describe :array_pack_arguments, shared: true do
|
||||
it "raises an ArgumentError if there are fewer elements than the format requires" do
|
||||
lambda { [].pack(pack_format(1)) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_basic, shared: true do
|
||||
before :each do
|
||||
@obj = ArraySpecs.universal_pack_object
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed nil" do
|
||||
lambda { [@obj].pack(nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed an Integer" do
|
||||
lambda { [@obj].pack(1) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_basic_non_float, shared: true do
|
||||
before :each do
|
||||
@obj = ArraySpecs.universal_pack_object
|
||||
end
|
||||
|
||||
it "ignores whitespace in the format string" do
|
||||
[@obj, @obj].pack("a \t\n\v\f\r"+pack_format).should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "calls #to_str to coerce the directives string" do
|
||||
d = mock("pack directive")
|
||||
d.should_receive(:to_str).and_return("x"+pack_format)
|
||||
[@obj, @obj].pack(d).should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "taints the output string if the format string is tainted" do
|
||||
[@obj, @obj].pack("x"+pack_format.taint).tainted?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_basic_float, shared: true do
|
||||
it "ignores whitespace in the format string" do
|
||||
[9.3, 4.7].pack(" \t\n\v\f\r"+pack_format).should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "calls #to_str to coerce the directives string" do
|
||||
d = mock("pack directive")
|
||||
d.should_receive(:to_str).and_return("x"+pack_format)
|
||||
[1.2, 4.7].pack(d).should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "taints the output string if the format string is tainted" do
|
||||
[3.2, 2.8].pack("x"+pack_format.taint).tainted?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_no_platform, shared: true do
|
||||
it "raises ArgumentError when the format modifier is '_'" do
|
||||
lambda{ [1].pack(pack_format("_")) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError when the format modifier is '!'" do
|
||||
lambda{ [1].pack(pack_format("!")) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
16
spec/ruby/core/array/pack/shared/encodings.rb
Normal file
16
spec/ruby/core/array/pack/shared/encodings.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
describe :array_pack_hex, shared: true do
|
||||
it "encodes no bytes when passed zero as the count modifier" do
|
||||
["abc"].pack(pack_format(0)).should == ""
|
||||
end
|
||||
|
||||
it "raises a TypeError if the object does not respond to #to_str" do
|
||||
obj = mock("pack hex non-string")
|
||||
lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_str does not return a String" do
|
||||
obj = mock("pack hex non-string")
|
||||
obj.should_receive(:to_str).and_return(1)
|
||||
lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
249
spec/ruby/core/array/pack/shared/float.rb
Normal file
249
spec/ruby/core/array/pack/shared/float.rb
Normal file
|
@ -0,0 +1,249 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
|
||||
describe :array_pack_float_le, shared: true do
|
||||
it "encodes a positive Float" do
|
||||
[1.42].pack(pack_format).should == "\x8f\xc2\xb5?"
|
||||
end
|
||||
|
||||
it "encodes a negative Float" do
|
||||
[-34.2].pack(pack_format).should == "\xcd\xcc\x08\xc2"
|
||||
end
|
||||
|
||||
it "converts an Integer to a Float" do
|
||||
[8].pack(pack_format).should == "\x00\x00\x00A"
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed a String representation of a floating point number" do
|
||||
lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format(nil, 2)).should == "\x9a\x999@33\xb3?"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format("*")).should == "\x9a\x999@33\xb3?33\x03A"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[5.3, 9.2].pack(pack_format("\000", 2)).should == "\x9a\x99\xa9@33\x13A"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[5.3, 9.2].pack(pack_format(" ", 2)).should == "\x9a\x99\xa9@33\x13A"
|
||||
end
|
||||
|
||||
it "encodes positive Infinity" do
|
||||
[infinity_value].pack(pack_format).should == "\x00\x00\x80\x7f"
|
||||
end
|
||||
|
||||
it "encodes negative Infinity" do
|
||||
[-infinity_value].pack(pack_format).should == "\x00\x00\x80\xff"
|
||||
end
|
||||
|
||||
platform_is "86" do # x86 / x86_64
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x00\x00\xc0\xff"
|
||||
end
|
||||
end
|
||||
|
||||
platform_is "powerpc64" do
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x00\x00\xc0\x7f"
|
||||
end
|
||||
end
|
||||
|
||||
it "encodes a positive Float outside the range of a single precision float" do
|
||||
[1e150].pack(pack_format).should == "\x00\x00\x80\x7f"
|
||||
end
|
||||
|
||||
it "encodes a negative Float outside the range of a single precision float" do
|
||||
[-1e150].pack(pack_format).should == "\x00\x00\x80\xff"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_float_be, shared: true do
|
||||
it "encodes a positive Float" do
|
||||
[1.42].pack(pack_format).should == "?\xb5\xc2\x8f"
|
||||
end
|
||||
|
||||
it "encodes a negative Float" do
|
||||
[-34.2].pack(pack_format).should == "\xc2\x08\xcc\xcd"
|
||||
end
|
||||
|
||||
it "converts an Integer to a Float" do
|
||||
[8].pack(pack_format).should == "A\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed a String representation of a floating point number" do
|
||||
lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format(nil, 2)).should == "@9\x99\x9a?\xb333"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format("*")).should == "@9\x99\x9a?\xb333A\x0333"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[5.3, 9.2].pack(pack_format("\000", 2)).should == "@\xa9\x99\x9aA\x1333"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[5.3, 9.2].pack(pack_format(" ", 2)).should == "@\xa9\x99\x9aA\x1333"
|
||||
end
|
||||
|
||||
it "encodes positive Infinity" do
|
||||
[infinity_value].pack(pack_format).should == "\x7f\x80\x00\x00"
|
||||
end
|
||||
|
||||
it "encodes negative Infinity" do
|
||||
[-infinity_value].pack(pack_format).should == "\xff\x80\x00\x00"
|
||||
end
|
||||
|
||||
platform_is "86" do # x86 / x86_64
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\xff\xc0\x00\x00"
|
||||
end
|
||||
end
|
||||
|
||||
platform_is "powerpc64" do
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x7f\xc0\x00\x00"
|
||||
end
|
||||
end
|
||||
|
||||
it "encodes a positive Float outside the range of a single precision float" do
|
||||
[1e150].pack(pack_format).should == "\x7f\x80\x00\x00"
|
||||
end
|
||||
|
||||
it "encodes a negative Float outside the range of a single precision float" do
|
||||
[-1e150].pack(pack_format).should == "\xff\x80\x00\x00"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_double_le, shared: true do
|
||||
it "encodes a positive Float" do
|
||||
[1.42].pack(pack_format).should == "\xb8\x1e\x85\xebQ\xb8\xf6?"
|
||||
end
|
||||
|
||||
it "encodes a negative Float" do
|
||||
[-34.2].pack(pack_format).should == "\x9a\x99\x99\x99\x99\x19A\xc0"
|
||||
end
|
||||
|
||||
it "converts an Integer to a Float" do
|
||||
[8].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\x20@"
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed a String representation of a floating point number" do
|
||||
lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format(nil, 2)).should == "333333\x07@ffffff\xf6?"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format("*")).should == "333333\x07@ffffff\xf6?ffffff\x20@"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[5.3, 9.2].pack(pack_format("\000", 2)).should == "333333\x15@ffffff\x22@"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[5.3, 9.2].pack(pack_format(" ", 2)).should == "333333\x15@ffffff\x22@"
|
||||
end
|
||||
|
||||
it "encodes positive Infinity" do
|
||||
[infinity_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf0\x7f"
|
||||
end
|
||||
|
||||
it "encodes negative Infinity" do
|
||||
[-infinity_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf0\xff"
|
||||
end
|
||||
|
||||
platform_is "86" do # x86 / x86_64
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf8\xff"
|
||||
end
|
||||
end
|
||||
|
||||
platform_is "powerpc64" do
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf8\x7f"
|
||||
end
|
||||
end
|
||||
|
||||
it "encodes a positive Float outside the range of a single precision float" do
|
||||
[1e150].pack(pack_format).should == "\xaf\x96P\x2e5\x8d\x13_"
|
||||
end
|
||||
|
||||
it "encodes a negative Float outside the range of a single precision float" do
|
||||
[-1e150].pack(pack_format).should == "\xaf\x96P\x2e5\x8d\x13\xdf"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_double_be, shared: true do
|
||||
it "encodes a positive Float" do
|
||||
[1.42].pack(pack_format).should == "?\xf6\xb8Q\xeb\x85\x1e\xb8"
|
||||
end
|
||||
|
||||
it "encodes a negative Float" do
|
||||
[-34.2].pack(pack_format).should == "\xc0A\x19\x99\x99\x99\x99\x9a"
|
||||
end
|
||||
|
||||
it "converts an Integer to a Float" do
|
||||
[8].pack(pack_format).should == "@\x20\x00\x00\x00\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed a String representation of a floating point number" do
|
||||
lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format(nil, 2)).should == "@\x07333333?\xf6ffffff"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[2.9, 1.4, 8.2].pack(pack_format("*")).should == "@\x07333333?\xf6ffffff@\x20ffffff"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[5.3, 9.2].pack(pack_format("\000", 2)).should == "@\x15333333@\x22ffffff"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[5.3, 9.2].pack(pack_format(" ", 2)).should == "@\x15333333@\x22ffffff"
|
||||
end
|
||||
|
||||
it "encodes positive Infinity" do
|
||||
[infinity_value].pack(pack_format).should == "\x7f\xf0\x00\x00\x00\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "encodes negative Infinity" do
|
||||
[-infinity_value].pack(pack_format).should == "\xff\xf0\x00\x00\x00\x00\x00\x00"
|
||||
end
|
||||
|
||||
platform_is "86" do # x86 / x86_64
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\xff\xf8\x00\x00\x00\x00\x00\x00"
|
||||
end
|
||||
end
|
||||
|
||||
platform_is "powerpc64" do
|
||||
it "encodes NaN" do
|
||||
[nan_value].pack(pack_format).should == "\x7f\xf8\x00\x00\x00\x00\x00\x00"
|
||||
end
|
||||
end
|
||||
|
||||
it "encodes a positive Float outside the range of a single precision float" do
|
||||
[1e150].pack(pack_format).should == "_\x13\x8d5\x2eP\x96\xaf"
|
||||
end
|
||||
|
||||
it "encodes a negative Float outside the range of a single precision float" do
|
||||
[-1e150].pack(pack_format).should == "\xdf\x13\x8d5\x2eP\x96\xaf"
|
||||
end
|
||||
end
|
381
spec/ruby/core/array/pack/shared/integer.rb
Normal file
381
spec/ruby/core/array/pack/shared/integer.rb
Normal file
|
@ -0,0 +1,381 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
|
||||
describe :array_pack_16bit_le, shared: true do
|
||||
it "encodes the least significant 16 bits of a positive number" do
|
||||
[ [[0x0000_0021], "\x21\x00"],
|
||||
[[0x0000_4321], "\x21\x43"],
|
||||
[[0x0065_4321], "\x21\x43"],
|
||||
[[0x7865_4321], "\x21\x43"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 16 bits of a negative number" do
|
||||
[ [[-0x0000_0021], "\xdf\xff"],
|
||||
[[-0x0000_4321], "\xdf\xbc"],
|
||||
[[-0x0065_4321], "\xdf\xbc"],
|
||||
[[-0x7865_4321], "\xdf\xbc"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[2019902241.2], "\x21\x43"],
|
||||
[[2019902241.8], "\x21\x43"],
|
||||
[[-2019902241.2], "\xdf\xbc"],
|
||||
[[-2019902241.8], "\xdf\xbc"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678)
|
||||
[obj].pack(pack_format()).should == "\x78\x56"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x78\x65\xcd\xab"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x78\x65\xcd\xab\x21\x43"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
|
||||
str.should == "\x78\x65\xcd\xab"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
|
||||
str.should == "\x78\x65\xcd\xab"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_16bit_be, shared: true do
|
||||
it "encodes the least significant 16 bits of a positive number" do
|
||||
[ [[0x0000_0021], "\x00\x21"],
|
||||
[[0x0000_4321], "\x43\x21"],
|
||||
[[0x0065_4321], "\x43\x21"],
|
||||
[[0x7865_4321], "\x43\x21"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 16 bits of a negative number" do
|
||||
[ [[-0x0000_0021], "\xff\xdf"],
|
||||
[[-0x0000_4321], "\xbc\xdf"],
|
||||
[[-0x0065_4321], "\xbc\xdf"],
|
||||
[[-0x7865_4321], "\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[2019902241.2], "\x43\x21"],
|
||||
[[2019902241.8], "\x43\x21"],
|
||||
[[-2019902241.2], "\xbc\xdf"],
|
||||
[[-2019902241.8], "\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678)
|
||||
[obj].pack(pack_format()).should == "\x56\x78"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x65\x78\xab\xcd"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x65\x78\xab\xcd\x43\x21"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
|
||||
str.should == "\x65\x78\xab\xcd"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
|
||||
str.should == "\x65\x78\xab\xcd"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_32bit_le, shared: true do
|
||||
it "encodes the least significant 32 bits of a positive number" do
|
||||
[ [[0x0000_0021], "\x21\x00\x00\x00"],
|
||||
[[0x0000_4321], "\x21\x43\x00\x00"],
|
||||
[[0x0065_4321], "\x21\x43\x65\x00"],
|
||||
[[0x7865_4321], "\x21\x43\x65\x78"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 32 bits of a negative number" do
|
||||
[ [[-0x0000_0021], "\xdf\xff\xff\xff"],
|
||||
[[-0x0000_4321], "\xdf\xbc\xff\xff"],
|
||||
[[-0x0065_4321], "\xdf\xbc\x9a\xff"],
|
||||
[[-0x7865_4321], "\xdf\xbc\x9a\x87"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[2019902241.2], "\x21\x43\x65\x78"],
|
||||
[[2019902241.8], "\x21\x43\x65\x78"],
|
||||
[[-2019902241.2], "\xdf\xbc\x9a\x87"],
|
||||
[[-2019902241.8], "\xdf\xbc\x9a\x87"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678)
|
||||
[obj].pack(pack_format()).should == "\x78\x56\x34\x12"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_32bit_be, shared: true do
|
||||
it "encodes the least significant 32 bits of a positive number" do
|
||||
[ [[0x0000_0021], "\x00\x00\x00\x21"],
|
||||
[[0x0000_4321], "\x00\x00\x43\x21"],
|
||||
[[0x0065_4321], "\x00\x65\x43\x21"],
|
||||
[[0x7865_4321], "\x78\x65\x43\x21"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 32 bits of a negative number" do
|
||||
[ [[-0x0000_0021], "\xff\xff\xff\xdf"],
|
||||
[[-0x0000_4321], "\xff\xff\xbc\xdf"],
|
||||
[[-0x0065_4321], "\xff\x9a\xbc\xdf"],
|
||||
[[-0x7865_4321], "\x87\x9a\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[2019902241.2], "\x78\x65\x43\x21"],
|
||||
[[2019902241.8], "\x78\x65\x43\x21"],
|
||||
[[-2019902241.2], "\x87\x9a\xbc\xdf"],
|
||||
[[-2019902241.8], "\x87\x9a\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678)
|
||||
[obj].pack(pack_format()).should == "\x12\x34\x56\x78"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_32bit_le_platform, shared: true do
|
||||
it "encodes the least significant 32 bits of a number" do
|
||||
[ [[0x7865_4321], "\x21\x43\x65\x78"],
|
||||
[[-0x7865_4321], "\xdf\xbc\x9a\x87"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78"
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
|
||||
[ [[0xff_7865_4321], "\x21\x43\x65\x78"],
|
||||
[[-0xff_7865_4321], "\xdf\xbc\x9a\x87"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_32bit_be_platform, shared: true do
|
||||
it "encodes the least significant 32 bits of a number" do
|
||||
[ [[0x7865_4321], "\x78\x65\x43\x21"],
|
||||
[[-0x7865_4321], "\x87\x9a\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
|
||||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21"
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
|
||||
[ [[0xff_7865_4321], "\x78\x65\x43\x21"],
|
||||
[[-0xff_7865_4321], "\x87\x9a\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_64bit_le, shared: true do
|
||||
it "encodes the least significant 64 bits of a positive number" do
|
||||
[ [[0x0000_0000_0000_0021], "\x21\x00\x00\x00\x00\x00\x00\x00"],
|
||||
[[0x0000_0000_0000_4321], "\x21\x43\x00\x00\x00\x00\x00\x00"],
|
||||
[[0x0000_0000_0065_4321], "\x21\x43\x65\x00\x00\x00\x00\x00"],
|
||||
[[0x0000_0000_7865_4321], "\x21\x43\x65\x78\x00\x00\x00\x00"],
|
||||
[[0x0000_0090_7865_4321], "\x21\x43\x65\x78\x90\x00\x00\x00"],
|
||||
[[0x0000_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\x00\x00"],
|
||||
[[0x00dc_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\xdc\x00"],
|
||||
[[0x7edc_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\xdc\x7e"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 64 bits of a negative number" do
|
||||
[ [[-0x0000_0000_0000_0021], "\xdf\xff\xff\xff\xff\xff\xff\xff"],
|
||||
[[-0x0000_0000_0000_4321], "\xdf\xbc\xff\xff\xff\xff\xff\xff"],
|
||||
[[-0x0000_0000_0065_4321], "\xdf\xbc\x9a\xff\xff\xff\xff\xff"],
|
||||
[[-0x0000_0000_7865_4321], "\xdf\xbc\x9a\x87\xff\xff\xff\xff"],
|
||||
[[-0x0000_0090_7865_4321], "\xdf\xbc\x9a\x87\x6f\xff\xff\xff"],
|
||||
[[-0x0000_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\xff\xff"],
|
||||
[[-0x00dc_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\x23\xff"],
|
||||
[[-0x7edc_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\x23\x81"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[9.14138647331322368e+18], "\x00\x44\x65\x78\x90\xba\xdc\x7e"],
|
||||
[[-9.14138647331322368e+18], "\x00\xbc\x9a\x87\x6f\x45\x23\x81"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678_90ab_cdef)
|
||||
[obj].pack(pack_format()).should == "\xef\xcd\xab\x90\x78\x56\x34\x12"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1234_5678_90ab_cdef,
|
||||
0xdef0_abcd_3412_7856,
|
||||
0x7865_4321_dcba_def0].pack(pack_format(2))
|
||||
str.should == "\xef\xcd\xab\x90\x78\x56\x34\x12\x56\x78\x12\x34\xcd\xab\xf0\xde"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format('*'))
|
||||
str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
|
||||
str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format(' ', 2))
|
||||
str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_64bit_be, shared: true do
|
||||
it "encodes the least significant 64 bits of a positive number" do
|
||||
[ [[0x0000_0000_0000_0021], "\x00\x00\x00\x00\x00\x00\x00\x21"],
|
||||
[[0x0000_0000_0000_4321], "\x00\x00\x00\x00\x00\x00\x43\x21"],
|
||||
[[0x0000_0000_0065_4321], "\x00\x00\x00\x00\x00\x65\x43\x21"],
|
||||
[[0x0000_0000_7865_4321], "\x00\x00\x00\x00\x78\x65\x43\x21"],
|
||||
[[0x0000_0090_7865_4321], "\x00\x00\x00\x90\x78\x65\x43\x21"],
|
||||
[[0x0000_ba90_7865_4321], "\x00\x00\xba\x90\x78\x65\x43\x21"],
|
||||
[[0x00dc_ba90_7865_4321], "\x00\xdc\xba\x90\x78\x65\x43\x21"],
|
||||
[[0x7edc_ba90_7865_4321], "\x7e\xdc\xba\x90\x78\x65\x43\x21"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes the least significant 64 bits of a negative number" do
|
||||
[ [[-0x0000_0000_0000_0021], "\xff\xff\xff\xff\xff\xff\xff\xdf"],
|
||||
[[-0x0000_0000_0000_4321], "\xff\xff\xff\xff\xff\xff\xbc\xdf"],
|
||||
[[-0x0000_0000_0065_4321], "\xff\xff\xff\xff\xff\x9a\xbc\xdf"],
|
||||
[[-0x0000_0000_7865_4321], "\xff\xff\xff\xff\x87\x9a\xbc\xdf"],
|
||||
[[-0x0000_0090_7865_4321], "\xff\xff\xff\x6f\x87\x9a\xbc\xdf"],
|
||||
[[-0x0000_ba90_7865_4321], "\xff\xff\x45\x6f\x87\x9a\xbc\xdf"],
|
||||
[[-0x00dc_ba90_7865_4321], "\xff\x23\x45\x6f\x87\x9a\xbc\xdf"],
|
||||
[[-0x7edc_ba90_7865_4321], "\x81\x23\x45\x6f\x87\x9a\xbc\xdf"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "encodes a Float truncated as an Integer" do
|
||||
[ [[9.14138647331322368e+18], "\x7e\xdc\xba\x90\x78\x65\x44\x00"],
|
||||
[[-9.14138647331322368e+18], "\x81\x23\x45\x6f\x87\x9a\xbc\x00"]
|
||||
].should be_computed_by(:pack, pack_format())
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(0x1234_5678_90ab_cdef)
|
||||
[obj].pack(pack_format()).should == "\x12\x34\x56\x78\x90\xab\xcd\xef"
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
str = [0x1234_5678_90ab_cdef,
|
||||
0xdef0_abcd_3412_7856,
|
||||
0x7865_4321_dcba_def0].pack(pack_format(2))
|
||||
str.should == "\x12\x34\x56\x78\x90\xab\xcd\xef\xde\xf0\xab\xcd\x34\x12\x78\x56"
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format('*'))
|
||||
str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
|
||||
str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format(' ', 2))
|
||||
str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
|
||||
end
|
||||
end
|
44
spec/ruby/core/array/pack/shared/numeric_basic.rb
Normal file
44
spec/ruby/core/array/pack/shared/numeric_basic.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
describe :array_pack_numeric_basic, shared: true do
|
||||
it "returns an empty String if count is zero" do
|
||||
[1].pack(pack_format(0)).should == ""
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed nil" do
|
||||
lambda { [nil].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed true" do
|
||||
lambda { [true].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed false" do
|
||||
lambda { [false].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
[0xFF].pack(pack_format).encoding.should == Encoding::ASCII_8BIT
|
||||
[0xE3, 0x81, 0x82].pack(pack_format(3)).encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_integer, shared: true do
|
||||
it "raises a TypeError when the object does not respond to #to_int" do
|
||||
obj = mock('not an integer')
|
||||
lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a String" do
|
||||
lambda { ["5"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :array_pack_float, shared: true do
|
||||
it "raises a TypeError if a String does not represent a floating point number" do
|
||||
lambda { ["a"].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the object does not respond to #to_f" do
|
||||
obj = mock('not an float')
|
||||
lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
80
spec/ruby/core/array/pack/shared/string.rb
Normal file
80
spec/ruby/core/array/pack/shared/string.rb
Normal file
|
@ -0,0 +1,80 @@
|
|||
# -*- encoding: binary -*-
|
||||
describe :array_pack_string, shared: true do
|
||||
it "adds count bytes of a String to the output" do
|
||||
["abc"].pack(pack_format(2)).should == "ab"
|
||||
end
|
||||
|
||||
it "implicitly has a count of one when no count is specified" do
|
||||
["abc"].pack(pack_format).should == "a"
|
||||
end
|
||||
|
||||
it "does not add any bytes when the count is zero" do
|
||||
["abc"].pack(pack_format(0)).should == ""
|
||||
end
|
||||
|
||||
it "is not affected by a previous count modifier" do
|
||||
["abcde", "defg"].pack(pack_format(3)+pack_format).should == "abcd"
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when the Array is empty" do
|
||||
lambda { [].pack(pack_format) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when the Array has too few elements" do
|
||||
lambda { ["a"].pack(pack_format(nil, 2)) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the element to a String" do
|
||||
obj = mock('pack string')
|
||||
obj.should_receive(:to_str).and_return("abc")
|
||||
|
||||
[obj].pack(pack_format).should == "a"
|
||||
end
|
||||
|
||||
it "raises a TypeError when the object does not respond to #to_str" do
|
||||
obj = mock("not a string")
|
||||
lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns a tainted string when a pack argument is tainted" do
|
||||
["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true
|
||||
end
|
||||
|
||||
it "does not return a tainted string when the array is tainted" do
|
||||
["abcd", 0x20].taint.pack(pack_format("3C")).tainted?.should be_false
|
||||
end
|
||||
|
||||
it "returns a tainted string when the format is tainted" do
|
||||
["abcd", 0x20].pack(pack_format("3C").taint).tainted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a tainted string when an empty format is tainted" do
|
||||
["abcd", 0x20].pack("".taint).tainted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a untrusted string when the format is untrusted" do
|
||||
["abcd", 0x20].pack(pack_format("3C").untrust).untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a untrusted string when the empty format is untrusted" do
|
||||
["abcd", 0x20].pack("".untrust).untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a untrusted string when a pack argument is untrusted" do
|
||||
["abcd".untrust, 0x20].pack(pack_format("3C")).untrusted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a trusted string when the array is untrusted" do
|
||||
["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false
|
||||
end
|
||||
|
||||
it "returns a string in encoding of common to the concatenated results" do
|
||||
f = pack_format("*")
|
||||
[ [["\u{3042 3044 3046 3048}", 0x2000B].pack(f+"U"), Encoding::ASCII_8BIT],
|
||||
[["abcde\xd1", "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::ASCII_8BIT],
|
||||
[["a".force_encoding("ascii"), "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::ASCII_8BIT],
|
||||
# under discussion [ruby-dev:37294]
|
||||
[["\u{3042 3044 3046 3048}", 1].pack(f+"N"), Encoding::ASCII_8BIT]
|
||||
].should be_computed_by(:encoding)
|
||||
end
|
||||
end
|
94
spec/ruby/core/array/pack/shared/unicode.rb
Normal file
94
spec/ruby/core/array/pack/shared/unicode.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
describe :array_pack_unicode, shared: true do
|
||||
it "encodes ASCII values as a Unicode codepoint" do
|
||||
[ [[0], "\x00"],
|
||||
[[1], "\x01"],
|
||||
[[8], "\x08"],
|
||||
[[15], "\x0f"],
|
||||
[[24], "\x18"],
|
||||
[[31], "\x1f"],
|
||||
[[127], "\x7f"],
|
||||
[[128], "\xc2\x80"],
|
||||
[[129], "\xc2\x81"],
|
||||
[[255], "\xc3\xbf"]
|
||||
].should be_computed_by(:pack, "U")
|
||||
end
|
||||
|
||||
it "encodes UTF-8 BMP codepoints" do
|
||||
[ [[0x80], "\xc2\x80"],
|
||||
[[0x7ff], "\xdf\xbf"],
|
||||
[[0x800], "\xe0\xa0\x80"],
|
||||
[[0xffff], "\xef\xbf\xbf"]
|
||||
].should be_computed_by(:pack, "U")
|
||||
end
|
||||
|
||||
it "constructs strings with valid encodings" do
|
||||
str = [0x85].pack("U*")
|
||||
str.should == "\xc2\x85"
|
||||
str.valid_encoding?.should be_true
|
||||
end
|
||||
|
||||
it "encodes values larger than UTF-8 max codepoints" do
|
||||
[
|
||||
[[0x00110000], [244, 144, 128, 128].pack('C*').force_encoding('utf-8')],
|
||||
[[0x04000000], [252, 132, 128, 128, 128, 128].pack('C*').force_encoding('utf-8')],
|
||||
[[0x7FFFFFFF], [253, 191, 191, 191, 191, 191].pack('C*').force_encoding('utf-8')]
|
||||
].should be_computed_by(:pack, "U")
|
||||
end
|
||||
|
||||
it "encodes UTF-8 max codepoints" do
|
||||
[ [[0x10000], "\xf0\x90\x80\x80"],
|
||||
[[0xfffff], "\xf3\xbf\xbf\xbf"],
|
||||
[[0x100000], "\xf4\x80\x80\x80"],
|
||||
[[0x10ffff], "\xf4\x8f\xbf\xbf"]
|
||||
].should be_computed_by(:pack, "U")
|
||||
end
|
||||
|
||||
it "encodes the number of array elements specified by the count modifier" do
|
||||
[ [[0x41, 0x42, 0x43, 0x44], "U2", "\x41\x42"],
|
||||
[[0x41, 0x42, 0x43, 0x44], "U2U", "\x41\x42\x43"]
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "encodes all remaining elements when passed the '*' modifier" do
|
||||
[0x41, 0x42, 0x43, 0x44].pack("U*").should == "\x41\x42\x43\x44"
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(5)
|
||||
[obj].pack("U").should == "\x05"
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_int does not return an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return("5")
|
||||
lambda { [obj].pack("U") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[1, 2, 3].pack("U\x00U").should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[1, 2, 3].pack("U U").should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "raises a RangeError if passed a negative number" do
|
||||
lambda { [-1].pack("U") }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "raises a RangeError if passed a number larger than an unsigned 32-bit integer" do
|
||||
lambda { [2**32].pack("U") }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "sets the output string to UTF-8 encoding" do
|
||||
[ [[0x00].pack("U"), Encoding::UTF_8],
|
||||
[[0x41].pack("U"), Encoding::UTF_8],
|
||||
[[0x7F].pack("U"), Encoding::UTF_8],
|
||||
[[0x80].pack("U"), Encoding::UTF_8],
|
||||
[[0x10FFFF].pack("U"), Encoding::UTF_8]
|
||||
].should be_computed_by(:encoding)
|
||||
end
|
||||
end
|
128
spec/ruby/core/array/pack/u_spec.rb
Normal file
128
spec/ruby/core/array/pack/u_spec.rb
Normal file
|
@ -0,0 +1,128 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/unicode', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'U'" do
|
||||
it_behaves_like :array_pack_basic, 'U'
|
||||
it_behaves_like :array_pack_basic_non_float, 'U'
|
||||
it_behaves_like :array_pack_arguments, 'U'
|
||||
it_behaves_like :array_pack_unicode, 'U'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'u'" do
|
||||
it_behaves_like :array_pack_basic, 'u'
|
||||
it_behaves_like :array_pack_basic_non_float, 'u'
|
||||
it_behaves_like :array_pack_arguments, 'u'
|
||||
|
||||
it "encodes an empty string as an empty string" do
|
||||
[""].pack("u").should == ""
|
||||
end
|
||||
|
||||
it "appends a newline to the end of the encoded string" do
|
||||
["a"].pack("u").should == "!80``\n"
|
||||
end
|
||||
|
||||
it "encodes one element per directive" do
|
||||
["abc", "DEF"].pack("uu").should == "#86)C\n#1$5&\n"
|
||||
end
|
||||
|
||||
it "prepends the length of each segment of the input string as the first character (+32) in each line of the output" do
|
||||
["abcdefghijklm"].pack("u7").should == "&86)C9&5F\n&9VAI:FML\n!;0``\n"
|
||||
end
|
||||
|
||||
it "encodes 1, 2, or 3 characters in 4 output characters (uuencoding)" do
|
||||
[ [["a"], "!80``\n"],
|
||||
[["ab"], "\"86(`\n"],
|
||||
[["abc"], "#86)C\n"],
|
||||
[["abcd"], "$86)C9```\n"],
|
||||
[["abcde"], "%86)C9&4`\n"],
|
||||
[["abcdef"], "&86)C9&5F\n"],
|
||||
[["abcdefg"], "'86)C9&5F9P``\n"],
|
||||
].should be_computed_by(:pack, "u")
|
||||
end
|
||||
|
||||
it "emits a newline after complete groups of count / 3 input characters when passed a count modifier" do
|
||||
["abcdefg"].pack("u3").should == "#86)C\n#9&5F\n!9P``\n"
|
||||
end
|
||||
|
||||
it "implicitly has a count of 45 when passed '*', 0, 1, 2 or no count modifier" do
|
||||
s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
r = "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n%86%A86$`\n"
|
||||
[ [[s], "u", r],
|
||||
[[s], "u*", r],
|
||||
[[s], "u0", r],
|
||||
[[s], "u1", r],
|
||||
[[s], "u2", r],
|
||||
].should be_computed_by(:pack)
|
||||
end
|
||||
|
||||
it "encodes all ascii characters" do
|
||||
[ [["\x00\x01\x02\x03\x04\x05\x06"], "'``$\"`P0%!@``\n"],
|
||||
[["\a\b\t\n\v\f\r"], "'!P@)\"@L,#0``\n"],
|
||||
[["\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"], ")\#@\\0$1(3%!46\n"],
|
||||
[["\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f"], ")%Q@9&AL<'1X?\n"],
|
||||
[["!\"\#$%&'()*+,-./"], "/(2(C)\"4F)R@I*BLL+2XO\n"],
|
||||
[["0123456789"], "*,\#$R,S0U-C<X.0``\n"],
|
||||
[[":;<=>?@"], "'.CL\\/3X_0```\n"],
|
||||
[["ABCDEFGHIJKLMNOPQRSTUVWXYZ"], ":04)#1$5&1TA)2DM,34Y/4%%24U155E=865H`\n"],
|
||||
[["[\\]^_`"], "&6UQ=7E]@\n"],
|
||||
[["abcdefghijklmnopqrstuvwxyz"], ":86)C9&5F9VAI:FML;6YO<'%R<W1U=G=X>7H`\n"],
|
||||
[["{|}~"], "$>WQ]?@``\n"],
|
||||
[["\x7f\xc2\x80\xc2\x81\xc2\x82\xc2\x83"], ")?\\*`PH'\"@L*#\n"],
|
||||
[["\xc2\x84\xc2\x85\xc2\x86\xc2\x87\xc2"], ")PH3\"A<*&PH?\"\n"],
|
||||
[["\x88\xc2\x89\xc2\x8a\xc2\x8b\xc2\x8c"], ")B,*)PHK\"B\\*,\n"],
|
||||
[["\xc2\x8d\xc2\x8e\xc2\x8f\xc2\x90\xc2"], ")PHW\"CL*/PI#\"\n"],
|
||||
[["\x91\xc2\x92\xc2\x93\xc2\x94\xc2\x95"], ")D<*2PI/\"E,*5\n"],
|
||||
[["\xc2\x96\xc2\x97\xc2\x98\xc2\x99\xc2"], ")PI;\"E\\*8PIG\"\n"],
|
||||
[["\x9a\xc2\x9b\xc2\x9c\xc2\x9d\xc2\x9e"], ")FL*;PIS\"G<*>\n"],
|
||||
[["\xc2\x9f\xc2\xa0\xc2\xa1\xc2\xa2\xc2"], ")PI_\"H,*APJ+\"\n"],
|
||||
[["\xa3\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa7"], ")H\\*DPJ7\"IL*G\n"],
|
||||
[["\xc2\xa8\xc2\xa9\xc2\xaa\xc2\xab\xc2"], ")PJC\"J<*JPJO\"\n"],
|
||||
[["\xac\xc2\xad\xc2\xae\xc2\xaf\xc2\xb0"], ")K,*MPJ[\"K\\*P\n"],
|
||||
[["\xc2\xb1\xc2\xb2\xc2\xb3\xc2\xb4\xc2"], ")PK'\"LL*SPK3\"\n"],
|
||||
[["\xb5\xc2\xb6\xc2\xb7\xc2\xb8\xc2\xb9"], ")M<*VPK?\"N,*Y\n"],
|
||||
[["\xc2\xba\xc2\xbb\xc2\xbc\xc2\xbd\xc2"], ")PKK\"N\\*\\PKW\"\n"],
|
||||
[["\xbe\xc2\xbf\xc3\x80\xc3\x81\xc3\x82"], ")OL*_PX#\#@<.\"\n"],
|
||||
[["\xc3\x83\xc3\x84\xc3\x85\xc3\x86\xc3"], ")PX/#A,.%PX;#\n"],
|
||||
[["\x87\xc3\x88\xc3\x89\xc3\x8a\xc3\x8b"], ")A\\.(PXG#BL.+\n"],
|
||||
[["\xc3\x8c\xc3\x8d\xc3\x8e\xc3\x8f\xc3"], ")PXS#C<..PX_#\n"],
|
||||
[["\x90\xc3\x91\xc3\x92\xc3\x93\xc3\x94"], ")D,.1PY+#D\\.4\n"],
|
||||
[["\xc3\x95\xc3\x96\xc3\x97\xc3\x98\xc3"], ")PY7#EL.7PYC#\n"],
|
||||
[["\x99\xc3\x9a\xc3\x9b\xc3\x9c\xc3\x9d"], ")F<.:PYO#G,.=\n"],
|
||||
[["\xc3\x9e\xc3\x9f\xc3\xa0\xc3\xa1\xc3"], ")PY[#G\\.@PZ'#\n"],
|
||||
[["\xa2\xc3\xa3\xc3\xa4\xc3\xa5\xc3\xa6"], ")HL.CPZ3#I<.F\n"],
|
||||
[["\xc3\xa7\xc3\xa8\xc3\xa9\xc3\xaa\xc3"], ")PZ?#J,.IPZK#\n"],
|
||||
[["\xab\xc3\xac\xc3\xad\xc3\xae\xc3\xaf"], ")J\\.LPZW#KL.O\n"],
|
||||
[["\xc3\xb0\xc3\xb1\xc3\xb2\xc3\xb3\xc3"], ")P[##L<.RP[/#\n"],
|
||||
[["\xb4\xc3\xb5\xc3\xb6\xc3\xb7\xc3\xb8"], ")M,.UP[;#M\\.X\n"],
|
||||
[["\xc3\xb9\xc3\xba\xc3\xbb\xc3\xbc\xc3"], ")P[G#NL.[P[S#\n"],
|
||||
[["\xbd\xc3\xbe\xc3\xbf"], "%O<.^P[\\`\n"]
|
||||
].should be_computed_by(:pack, "u")
|
||||
end
|
||||
|
||||
it "calls #to_str to convert an object to a String" do
|
||||
obj = mock("pack m string")
|
||||
obj.should_receive(:to_str).and_return("abc")
|
||||
[obj].pack("u").should == "#86)C\n"
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_str does not return a String" do
|
||||
obj = mock("pack m non-string")
|
||||
lambda { [obj].pack("u") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed nil" do
|
||||
lambda { [nil].pack("u") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if passed an Integer" do
|
||||
lambda { [0].pack("u") }.should raise_error(TypeError)
|
||||
lambda { [bignum_value].pack("u") }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "sets the output string to US-ASCII encoding" do
|
||||
["abcd"].pack("u").encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
end
|
25
spec/ruby/core/array/pack/v_spec.rb
Normal file
25
spec/ruby/core/array/pack/v_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
require File.expand_path('../shared/integer', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'V'" do
|
||||
it_behaves_like :array_pack_basic, 'V'
|
||||
it_behaves_like :array_pack_basic_non_float, 'V'
|
||||
it_behaves_like :array_pack_arguments, 'V'
|
||||
it_behaves_like :array_pack_numeric_basic, 'V'
|
||||
it_behaves_like :array_pack_integer, 'V'
|
||||
it_behaves_like :array_pack_no_platform, 'V'
|
||||
it_behaves_like :array_pack_32bit_le, 'V'
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'v'" do
|
||||
it_behaves_like :array_pack_basic, 'v'
|
||||
it_behaves_like :array_pack_basic_non_float, 'v'
|
||||
it_behaves_like :array_pack_arguments, 'v'
|
||||
it_behaves_like :array_pack_numeric_basic, 'v'
|
||||
it_behaves_like :array_pack_integer, 'v'
|
||||
it_behaves_like :array_pack_no_platform, 'v'
|
||||
it_behaves_like :array_pack_16bit_le, 'v'
|
||||
end
|
42
spec/ruby/core/array/pack/w_spec.rb
Normal file
42
spec/ruby/core/array/pack/w_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/numeric_basic', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'w'" do
|
||||
it_behaves_like :array_pack_basic, 'w'
|
||||
it_behaves_like :array_pack_basic_non_float, 'w'
|
||||
it_behaves_like :array_pack_arguments, 'w'
|
||||
it_behaves_like :array_pack_numeric_basic, 'w'
|
||||
|
||||
it "encodes a BER-compressed integer" do
|
||||
[ [[0], "\x00"],
|
||||
[[1], "\x01"],
|
||||
[[9999], "\xce\x0f"],
|
||||
[[2**65], "\x84\x80\x80\x80\x80\x80\x80\x80\x80\x00"]
|
||||
].should be_computed_by(:pack, "w")
|
||||
end
|
||||
|
||||
it "calls #to_int to convert the pack argument to an Integer" do
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(5)
|
||||
[obj].pack("w").should == "\x05"
|
||||
end
|
||||
|
||||
it "ignores NULL bytes between directives" do
|
||||
[1, 2, 3].pack("w\x00w").should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "ignores spaces between directives" do
|
||||
[1, 2, 3].pack("w w").should == "\x01\x02"
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed a negative value" do
|
||||
lambda { [-1].pack("w") }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns an ASCII-8BIT string" do
|
||||
[1].pack('w').encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
end
|
64
spec/ruby/core/array/pack/x_spec.rb
Normal file
64
spec/ruby/core/array/pack/x_spec.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'x'" do
|
||||
it_behaves_like :array_pack_basic, 'x'
|
||||
it_behaves_like :array_pack_basic_non_float, 'x'
|
||||
it_behaves_like :array_pack_no_platform, 'x'
|
||||
|
||||
it "adds a NULL byte with an empty array" do
|
||||
[].pack("x").should == "\x00"
|
||||
end
|
||||
|
||||
it "adds a NULL byte without consuming an element" do
|
||||
[1, 2].pack("CxC").should == "\x01\x00\x02"
|
||||
end
|
||||
|
||||
it "is not affected by a previous count modifier" do
|
||||
[].pack("x3x").should == "\x00\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "adds multiple NULL bytes when passed a count modifier" do
|
||||
[].pack("x3").should == "\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "does not add a NULL byte if the count modifier is zero" do
|
||||
[].pack("x0").should == ""
|
||||
end
|
||||
|
||||
it "does not add a NULL byte when passed the '*' modifier" do
|
||||
[].pack("x*").should == ""
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#pack with format 'X'" do
|
||||
it_behaves_like :array_pack_basic, 'X'
|
||||
it_behaves_like :array_pack_basic_non_float, 'X'
|
||||
it_behaves_like :array_pack_no_platform, 'X'
|
||||
|
||||
it "reduces the output string by one byte at the point it is encountered" do
|
||||
[1, 2, 3].pack("C2XC").should == "\x01\x03"
|
||||
end
|
||||
|
||||
it "does not consume any elements" do
|
||||
[1, 2, 3].pack("CXC").should == "\x02"
|
||||
end
|
||||
|
||||
it "reduces the output string by multiple bytes when passed a count modifier" do
|
||||
[1, 2, 3, 4, 5].pack("C2X2C").should == "\x03"
|
||||
end
|
||||
|
||||
it "has no affect when passed the '*' modifier" do
|
||||
[1, 2, 3].pack("C2X*C").should == "\x01\x02\x03"
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if the output string is empty" do
|
||||
lambda { [1, 2, 3].pack("XC") }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if the count modifier is greater than the bytes in the string" do
|
||||
lambda { [1, 2, 3].pack("C2X3") }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
32
spec/ruby/core/array/pack/z_spec.rb
Normal file
32
spec/ruby/core/array/pack/z_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# -*- encoding: ascii-8bit -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/basic', __FILE__)
|
||||
require File.expand_path('../shared/string', __FILE__)
|
||||
|
||||
describe "Array#pack with format 'Z'" do
|
||||
it_behaves_like :array_pack_basic, 'Z'
|
||||
it_behaves_like :array_pack_basic_non_float, 'Z'
|
||||
it_behaves_like :array_pack_no_platform, 'Z'
|
||||
it_behaves_like :array_pack_string, 'Z'
|
||||
|
||||
it "adds all the bytes and appends a NULL byte when passed the '*' modifier" do
|
||||
["abc"].pack("Z*").should == "abc\x00"
|
||||
end
|
||||
|
||||
it "padds the output with NULL bytes when the count exceeds the size of the String" do
|
||||
["abc"].pack("Z6").should == "abc\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "adds a NULL byte when the value is nil" do
|
||||
[nil].pack("Z").should == "\x00"
|
||||
end
|
||||
|
||||
it "pads the output with NULL bytes when the value is nil" do
|
||||
[nil].pack("Z3").should == "\x00\x00\x00"
|
||||
end
|
||||
|
||||
it "does not append a NULL byte when passed the '*' modifier and the value is nil" do
|
||||
[nil].pack("Z*").should == "\x00"
|
||||
end
|
||||
end
|
43
spec/ruby/core/array/partition_spec.rb
Normal file
43
spec/ruby/core/array/partition_spec.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#partition" do
|
||||
it "returns two arrays" do
|
||||
[].partition {}.should == [[], []]
|
||||
end
|
||||
|
||||
it "returns in the left array values for which the block evaluates to true" do
|
||||
ary = [0, 1, 2, 3, 4, 5]
|
||||
|
||||
ary.partition { |i| true }.should == [ary, []]
|
||||
ary.partition { |i| 5 }.should == [ary, []]
|
||||
ary.partition { |i| false }.should == [[], ary]
|
||||
ary.partition { |i| nil }.should == [[], ary]
|
||||
ary.partition { |i| i % 2 == 0 }.should == [[0, 2, 4], [1, 3, 5]]
|
||||
ary.partition { |i| i / 3 == 0 }.should == [[0, 1, 2], [3, 4, 5]]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.partition { true }.should == [[empty], []]
|
||||
empty.partition { false }.should == [[], [empty]]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.partition { true }.should == [
|
||||
[1, 'two', 3.0, array, array, array, array, array],
|
||||
[]
|
||||
]
|
||||
condition = true
|
||||
array.partition { condition = !condition }.should == [
|
||||
['two', array, array, array],
|
||||
[1, 3.0, array, array]
|
||||
]
|
||||
end
|
||||
|
||||
it "does not return subclass instances on Array subclasses" do
|
||||
result = ArraySpecs::MyArray[1, 2, 3].partition { |x| x % 2 == 0 }
|
||||
result.should be_an_instance_of(Array)
|
||||
result[0].should be_an_instance_of(Array)
|
||||
result[1].should be_an_instance_of(Array)
|
||||
end
|
||||
end
|
138
spec/ruby/core/array/permutation_spec.rb
Normal file
138
spec/ruby/core/array/permutation_spec.rb
Normal file
|
@ -0,0 +1,138 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
|
||||
describe "Array#permutation" do
|
||||
|
||||
before :each do
|
||||
@numbers = (1..3).to_a
|
||||
@yielded = []
|
||||
end
|
||||
|
||||
it "returns an Enumerator of all permutations when called without a block or arguments" do
|
||||
enum = @numbers.permutation
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
enum.to_a.sort.should == [
|
||||
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
|
||||
].sort
|
||||
end
|
||||
|
||||
it "returns an Enumerator of permutations of given length when called with an argument but no block" do
|
||||
enum = @numbers.permutation(1)
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
enum.to_a.sort.should == [[1],[2],[3]]
|
||||
end
|
||||
|
||||
it "yields all permutations to the block then returns self when called with block but no arguments" do
|
||||
array = @numbers.permutation {|n| @yielded << n}
|
||||
array.should be_an_instance_of(Array)
|
||||
array.sort.should == @numbers.sort
|
||||
@yielded.sort.should == [
|
||||
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
|
||||
].sort
|
||||
end
|
||||
|
||||
it "yields all permutations of given length to the block then returns self when called with block and argument" do
|
||||
array = @numbers.permutation(2) {|n| @yielded << n}
|
||||
array.should be_an_instance_of(Array)
|
||||
array.sort.should == @numbers.sort
|
||||
@yielded.sort.should == [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]].sort
|
||||
end
|
||||
|
||||
it "returns the empty permutation ([[]]) when the given length is 0" do
|
||||
@numbers.permutation(0).to_a.should == [[]]
|
||||
@numbers.permutation(0) { |n| @yielded << n }
|
||||
@yielded.should == [[]]
|
||||
end
|
||||
|
||||
it "returns the empty permutation([]) when called on an empty Array" do
|
||||
[].permutation.to_a.should == [[]]
|
||||
[].permutation { |n| @yielded << n }
|
||||
@yielded.should == [[]]
|
||||
end
|
||||
|
||||
it "returns no permutations when the given length has no permutations" do
|
||||
@numbers.permutation(9).entries.size == 0
|
||||
@numbers.permutation(9) { |n| @yielded << n }
|
||||
@yielded.should == []
|
||||
end
|
||||
|
||||
it "handles duplicate elements correctly" do
|
||||
@numbers << 1
|
||||
@numbers.permutation(2).sort.should == [
|
||||
[1,1],[1,1],[1,2],[1,2],[1,3],[1,3],
|
||||
[2,1],[2,1],[2,3],
|
||||
[3,1],[3,1],[3,2]
|
||||
].sort
|
||||
end
|
||||
|
||||
it "handles nested Arrays correctly" do
|
||||
# The ugliness is due to the order of permutations returned by
|
||||
# permutation being undefined combined with #sort croaking on Arrays of
|
||||
# Arrays.
|
||||
@numbers << [4,5]
|
||||
got = @numbers.permutation(2).to_a
|
||||
expected = [
|
||||
[1, 2], [1, 3], [1, [4, 5]],
|
||||
[2, 1], [2, 3], [2, [4, 5]],
|
||||
[3, 1], [3, 2], [3, [4, 5]],
|
||||
[[4, 5], 1], [[4, 5], 2], [[4, 5], 3]
|
||||
]
|
||||
expected.each {|e| got.include?(e).should be_true}
|
||||
got.size.should == expected.size
|
||||
end
|
||||
|
||||
it "truncates Float arguments" do
|
||||
@numbers.permutation(3.7).to_a.sort.should ==
|
||||
@numbers.permutation(3).to_a.sort
|
||||
end
|
||||
|
||||
it "returns an Enumerator which works as expected even when the array was modified" do
|
||||
@numbers = [1, 2]
|
||||
enum = @numbers.permutation
|
||||
@numbers << 3
|
||||
enum.to_a.sort.should == [
|
||||
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
|
||||
].sort
|
||||
end
|
||||
|
||||
it "generates from a defensive copy, ignoring mutations" do
|
||||
accum = []
|
||||
ary = [1,2,3]
|
||||
ary.permutation(3) do |x|
|
||||
accum << x
|
||||
ary[0] = 5
|
||||
end
|
||||
|
||||
accum.should == [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
describe "with an array size greater than 0" do
|
||||
it "returns the descending factorial of array size and given length" do
|
||||
@numbers.permutation(4).size.should == 0
|
||||
@numbers.permutation(3).size.should == 6
|
||||
@numbers.permutation(2).size.should == 6
|
||||
@numbers.permutation(1).size.should == 3
|
||||
@numbers.permutation(0).size.should == 1
|
||||
end
|
||||
it "returns the descending factorial of array size with array size when there's no param" do
|
||||
@numbers.permutation.size.should == 6
|
||||
[1,2,3,4].permutation.size.should == 24
|
||||
[1].permutation.size.should == 1
|
||||
end
|
||||
end
|
||||
describe "with an empty array" do
|
||||
it "returns 1 when the given length is 0" do
|
||||
[].permutation(0).size.should == 1
|
||||
end
|
||||
it "returns 1 when there's param" do
|
||||
[].permutation.size.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
57
spec/ruby/core/array/plus_spec.rb
Normal file
57
spec/ruby/core/array/plus_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#+" do
|
||||
it "concatenates two arrays" do
|
||||
([ 1, 2, 3 ] + [ 3, 4, 5 ]).should == [1, 2, 3, 3, 4, 5]
|
||||
([ 1, 2, 3 ] + []).should == [1, 2, 3]
|
||||
([] + [ 1, 2, 3 ]).should == [1, 2, 3]
|
||||
([] + []).should == []
|
||||
end
|
||||
|
||||
it "can concatenate an array with itself" do
|
||||
ary = [1, 2, 3]
|
||||
(ary + ary).should == [1, 2, 3, 1, 2, 3]
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to an Array using #to_ary" do
|
||||
obj = mock('["x", "y"]')
|
||||
obj.should_receive(:to_ary).and_return(["x", "y"])
|
||||
([1, 2, 3] + obj).should == [1, 2, 3, "x", "y"]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
(empty + empty).should == [empty, empty]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
(empty + array).should == [empty, 1, 'two', 3.0, array, array, array, array, array]
|
||||
(array + array).should == [
|
||||
1, 'two', 3.0, array, array, array, array, array,
|
||||
1, 'two', 3.0, array, array, array, array, array]
|
||||
end
|
||||
|
||||
it "does return subclass instances with Array subclasses" do
|
||||
(ArraySpecs::MyArray[1, 2, 3] + []).should be_an_instance_of(Array)
|
||||
(ArraySpecs::MyArray[1, 2, 3] + ArraySpecs::MyArray[]).should be_an_instance_of(Array)
|
||||
([1, 2, 3] + ArraySpecs::MyArray[]).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "does not call to_ary on array subclasses" do
|
||||
([5, 6] + ArraySpecs::ToAryArray[1, 2]).should == [5, 6, 1, 2]
|
||||
end
|
||||
|
||||
it "does not get infected even if an original array is tainted" do
|
||||
([1, 2] + [3, 4]).tainted?.should be_false
|
||||
([1, 2].taint + [3, 4]).tainted?.should be_false
|
||||
([1, 2] + [3, 4].taint).tainted?.should be_false
|
||||
([1, 2].taint + [3, 4].taint).tainted?.should be_false
|
||||
end
|
||||
|
||||
it "does not infected even if an original array is untrusted" do
|
||||
([1, 2] + [3, 4]).untrusted?.should be_false
|
||||
([1, 2].untrust + [3, 4]).untrusted?.should be_false
|
||||
([1, 2] + [3, 4].untrust).untrusted?.should be_false
|
||||
([1, 2].untrust + [3, 4].untrust).untrusted?.should be_false
|
||||
end
|
||||
end
|
168
spec/ruby/core/array/pop_spec.rb
Normal file
168
spec/ruby/core/array/pop_spec.rb
Normal file
|
@ -0,0 +1,168 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#pop" do
|
||||
it "removes and returns the last element of the array" do
|
||||
a = ["a", 1, nil, true]
|
||||
|
||||
a.pop.should == true
|
||||
a.should == ["a", 1, nil]
|
||||
|
||||
a.pop.should == nil
|
||||
a.should == ["a", 1]
|
||||
|
||||
a.pop.should == 1
|
||||
a.should == ["a"]
|
||||
|
||||
a.pop.should == "a"
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "returns nil if there are no more elements" do
|
||||
[].pop.should == nil
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.pop.should == []
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.pop.should == [1, 'two', 3.0, array, array, array, array]
|
||||
end
|
||||
|
||||
it "keeps taint status" do
|
||||
a = [1, 2].taint
|
||||
a.pop
|
||||
a.tainted?.should be_true
|
||||
a.pop
|
||||
a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.pop }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on an empty frozen array" do
|
||||
lambda { ArraySpecs.empty_frozen_array.pop }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
a = [1, 2].untrust
|
||||
a.pop
|
||||
a.untrusted?.should be_true
|
||||
a.pop
|
||||
a.untrusted?.should be_true
|
||||
end
|
||||
|
||||
describe "passed a number n as an argument" do
|
||||
it "removes and returns an array with the last n elements of the array" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
|
||||
a.pop(0).should == []
|
||||
a.should == [1, 2, 3, 4, 5, 6]
|
||||
|
||||
a.pop(1).should == [6]
|
||||
a.should == [1, 2, 3, 4, 5]
|
||||
|
||||
a.pop(2).should == [4, 5]
|
||||
a.should == [1, 2, 3]
|
||||
|
||||
a.pop(3).should == [1, 2, 3]
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "returns an array with the last n elements even if shift was invoked" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.shift
|
||||
a.pop(3).should == [2, 3, 4]
|
||||
end
|
||||
|
||||
it "returns a new empty array if there are no more elements" do
|
||||
a = []
|
||||
popped1 = a.pop(1)
|
||||
popped1.should == []
|
||||
a.should == []
|
||||
|
||||
popped2 = a.pop(2)
|
||||
popped2.should == []
|
||||
a.should == []
|
||||
|
||||
popped1.should_not equal(popped2)
|
||||
end
|
||||
|
||||
it "returns whole elements if n exceeds size of the array" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a.pop(6).should == [1, 2, 3, 4, 5]
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "does not return self even when it returns whole elements" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a.pop(5).should_not equal(a)
|
||||
|
||||
a = [1, 2, 3, 4, 5]
|
||||
a.pop(6).should_not equal(a)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if n is negative" do
|
||||
lambda{ [1, 2, 3].pop(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "tries to convert n to an Integer using #to_int" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.pop(2.3).should == [3, 4]
|
||||
|
||||
obj = mock('to_int')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
a.should == [1, 2]
|
||||
a.pop(obj).should == [1, 2]
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "raises a TypeError when the passed n can be coerced to Integer" do
|
||||
lambda{ [1, 2].pop("cat") }.should raise_error(TypeError)
|
||||
lambda{ [1, 2].pop(nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if more arguments are passed" do
|
||||
lambda{ [1, 2].pop(1, 2) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "does not return subclass instances with Array subclass" do
|
||||
ArraySpecs::MyArray[1, 2, 3].pop(2).should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "returns an untainted array even if the array is tainted" do
|
||||
ary = [1, 2].taint
|
||||
ary.pop(2).tainted?.should be_false
|
||||
ary.pop(0).tainted?.should be_false
|
||||
end
|
||||
|
||||
it "keeps taint status" do
|
||||
a = [1, 2].taint
|
||||
a.pop(2)
|
||||
a.tainted?.should be_true
|
||||
a.pop(2)
|
||||
a.tainted?.should be_true
|
||||
end
|
||||
|
||||
it "returns a trusted array even if the array is untrusted" do
|
||||
ary = [1, 2].untrust
|
||||
ary.pop(2).untrusted?.should be_false
|
||||
ary.pop(0).untrusted?.should be_false
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.pop(2) }.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.frozen_array.pop(0) }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "keeps untrusted status" do
|
||||
a = [1, 2].untrust
|
||||
a.pop(2)
|
||||
a.untrusted?.should be_true
|
||||
a.pop(2)
|
||||
a.untrusted?.should be_true
|
||||
end
|
||||
end
|
||||
end
|
68
spec/ruby/core/array/product_spec.rb
Normal file
68
spec/ruby/core/array/product_spec.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#product" do
|
||||
it "returns converted arguments using :to_ary" do
|
||||
lambda{ [1].product(2..3) }.should raise_error(TypeError)
|
||||
ar = ArraySpecs::ArrayConvertable.new(2,3)
|
||||
[1].product(ar).should == [[1,2],[1,3]]
|
||||
ar.called.should == :to_ary
|
||||
end
|
||||
|
||||
it "returns the expected result" do
|
||||
[1,2].product([3,4,5],[6,8]).should == [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
|
||||
[2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]]
|
||||
end
|
||||
|
||||
it "has no required argument" do
|
||||
[1,2].product.should == [[1],[2]]
|
||||
end
|
||||
|
||||
it "returns an empty array when the argument is an empty array" do
|
||||
[1, 2].product([]).should == []
|
||||
end
|
||||
|
||||
it "does not attempt to produce an unreasonable number of products" do
|
||||
a = (0..100).to_a
|
||||
lambda do
|
||||
a.product(a, a, a, a, a, a, a, a, a, a)
|
||||
end.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
describe "when given a block" do
|
||||
it "yields all combinations in turn" do
|
||||
acc = []
|
||||
[1,2].product([3,4,5],[6,8]){|array| acc << array}
|
||||
acc.should == [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
|
||||
[2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]]
|
||||
|
||||
acc = []
|
||||
[1,2].product([3,4,5],[],[6,8]){|array| acc << array}
|
||||
acc.should be_empty
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
a = [1, 2, 3].freeze
|
||||
|
||||
a.product([1, 2]) { |p| p.first }.should == a
|
||||
end
|
||||
|
||||
it "will ignore unreasonable numbers of products and yield anyway" do
|
||||
a = (0..100).to_a
|
||||
lambda do
|
||||
a.product(a, a, a, a, a, a, a, a, a, a)
|
||||
end.should raise_error(RangeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when given an empty block" do
|
||||
it "returns self" do
|
||||
arr = [1,2]
|
||||
arr.product([3,4,5],[6,8]){}.should equal(arr)
|
||||
arr = []
|
||||
arr.product([3,4,5],[6,8]){}.should equal(arr)
|
||||
arr = [1,2]
|
||||
arr.product([]){}.should equal(arr)
|
||||
end
|
||||
end
|
||||
end
|
36
spec/ruby/core/array/push_spec.rb
Normal file
36
spec/ruby/core/array/push_spec.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#push" do
|
||||
it "appends the arguments to the array" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.push("d", "e", "f").should equal(a)
|
||||
a.push().should == ["a", "b", "c", "d", "e", "f"]
|
||||
a.push(5)
|
||||
a.should == ["a", "b", "c", "d", "e", "f", 5]
|
||||
|
||||
a = [0, 1]
|
||||
a.push(2)
|
||||
a.should == [0, 1, 2]
|
||||
end
|
||||
|
||||
it "isn't confused by previous shift" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.shift
|
||||
a.push("foo")
|
||||
a.should == ["b", "c", "foo"]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.push(:last).should == [empty, :last]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.push(:last).should == [1, 'two', 3.0, array, array, array, array, array, :last]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.push(1) }.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.frozen_array.push }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
38
spec/ruby/core/array/rassoc_spec.rb
Normal file
38
spec/ruby/core/array/rassoc_spec.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#rassoc" do
|
||||
it "returns the first contained array whose second element is == object" do
|
||||
ary = [[1, "a", 0.5], [2, "b"], [3, "b"], [4, "c"], [], [5], [6, "d"]]
|
||||
ary.rassoc("a").should == [1, "a", 0.5]
|
||||
ary.rassoc("b").should == [2, "b"]
|
||||
ary.rassoc("d").should == [6, "d"]
|
||||
ary.rassoc("z").should == nil
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.rassoc([]).should be_nil
|
||||
[[empty, empty]].rassoc(empty).should == [empty, empty]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.rassoc(array).should be_nil
|
||||
[[empty, array]].rassoc(array).should == [empty, array]
|
||||
end
|
||||
|
||||
it "calls elem == obj on the second element of each contained array" do
|
||||
key = 'foobar'
|
||||
o = mock('foobar')
|
||||
def o.==(other); other == 'foobar'; end
|
||||
|
||||
[[1, :foobar], [2, o], [3, mock('foo')]].rassoc(key).should == [2, o]
|
||||
end
|
||||
|
||||
it "does not check the last element in each contained but speficically the second" do
|
||||
key = 'foobar'
|
||||
o = mock('foobar')
|
||||
def o.==(other); other == 'foobar'; end
|
||||
|
||||
[[1, :foobar, o], [2, o, 1], [3, mock('foo')]].rassoc(key).should == [2, o, 1]
|
||||
end
|
||||
end
|
117
spec/ruby/core/array/reject_spec.rb
Normal file
117
spec/ruby/core/array/reject_spec.rb
Normal file
|
@ -0,0 +1,117 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/enumeratorize', __FILE__)
|
||||
require File.expand_path('../shared/delete_if', __FILE__)
|
||||
require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
|
||||
|
||||
describe "Array#reject" do
|
||||
it "returns a new array without elements for which block is true" do
|
||||
ary = [1, 2, 3, 4, 5]
|
||||
ary.reject { true }.should == []
|
||||
ary.reject { false }.should == ary
|
||||
ary.reject { false }.object_id.should_not == ary.object_id
|
||||
ary.reject { nil }.should == ary
|
||||
ary.reject { nil }.object_id.should_not == ary.object_id
|
||||
ary.reject { 5 }.should == []
|
||||
ary.reject { |i| i < 3 }.should == [3, 4, 5]
|
||||
ary.reject { |i| i % 2 == 0 }.should == [1, 3, 5]
|
||||
end
|
||||
|
||||
it "returns self when called on an Array emptied with #shift" do
|
||||
array = [1]
|
||||
array.shift
|
||||
array.reject { |x| true }.should == []
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.reject { false }.should == [empty]
|
||||
empty.reject { true }.should == []
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.reject { false }.should == [1, 'two', 3.0, array, array, array, array, array]
|
||||
array.reject { true }.should == []
|
||||
end
|
||||
|
||||
it "does not return subclass instance on Array subclasses" do
|
||||
ArraySpecs::MyArray[1, 2, 3].reject { |x| x % 2 == 0 }.should be_an_instance_of(Array)
|
||||
end
|
||||
|
||||
it "does not retain instance variables" do
|
||||
array = []
|
||||
array.instance_variable_set("@variable", "value")
|
||||
array.reject { false }.instance_variable_get("@variable").should == nil
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorize, :reject
|
||||
it_behaves_like :enumeratorized_with_origin_size, :reject, [1,2,3]
|
||||
end
|
||||
|
||||
describe "Array#reject!" do
|
||||
it "removes elements for which block is true" do
|
||||
a = [3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
a.reject! { |i| i % 2 == 0 }.should equal(a)
|
||||
a.should == [3, 5, 7, 9, 11]
|
||||
a.reject! { |i| i > 8 }
|
||||
a.should == [3, 5, 7]
|
||||
a.reject! { |i| i < 4 }
|
||||
a.should == [5, 7]
|
||||
a.reject! { |i| i == 5 }
|
||||
a.should == [7]
|
||||
a.reject! { true }
|
||||
a.should == []
|
||||
a.reject! { true }
|
||||
a.should == []
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty_dup = empty.dup
|
||||
empty.reject! { false }.should == nil
|
||||
empty.should == empty_dup
|
||||
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.reject! { true }.should == []
|
||||
empty.should == []
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array_dup = array.dup
|
||||
array.reject! { false }.should == nil
|
||||
array.should == array_dup
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.reject! { true }.should == []
|
||||
array.should == []
|
||||
end
|
||||
|
||||
it "returns nil when called on an Array emptied with #shift" do
|
||||
array = [1]
|
||||
array.shift
|
||||
array.reject! { |x| true }.should == nil
|
||||
end
|
||||
|
||||
it "returns nil if no changes are made" do
|
||||
a = [1, 2, 3]
|
||||
|
||||
a.reject! { |i| i < 0 }.should == nil
|
||||
|
||||
a.reject! { true }
|
||||
a.reject! { true }.should == nil
|
||||
end
|
||||
|
||||
it "returns an Enumerator if no block given, and the array is frozen" do
|
||||
ArraySpecs.frozen_array.reject!.should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.reject! {} }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on an empty frozen array" do
|
||||
lambda { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it_behaves_like :enumeratorize, :reject!
|
||||
it_behaves_like :enumeratorized_with_origin_size, :reject!, [1,2,3]
|
||||
it_behaves_like :delete_if, :reject!
|
||||
end
|
84
spec/ruby/core/array/repeated_combination_spec.rb
Normal file
84
spec/ruby/core/array/repeated_combination_spec.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe "Array#repeated_combination" do
|
||||
before :each do
|
||||
@array = [10, 11, 12]
|
||||
end
|
||||
|
||||
it "returns an enumerator when no block is provided" do
|
||||
@array.repeated_combination(2).should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "returns self when a block is given" do
|
||||
@array.repeated_combination(2){}.should equal(@array)
|
||||
end
|
||||
|
||||
it "yields nothing for negative length and return self" do
|
||||
@array.repeated_combination(-1){ fail }.should equal(@array)
|
||||
@array.repeated_combination(-10){ fail }.should equal(@array)
|
||||
end
|
||||
|
||||
it "yields the expected repeated_combinations" do
|
||||
@array.repeated_combination(2).to_a.sort.should == [[10, 10], [10, 11], [10, 12], [11, 11], [11, 12], [12, 12]]
|
||||
@array.repeated_combination(3).to_a.sort.should == [[10, 10, 10], [10, 10, 11], [10, 10, 12], [10, 11, 11], [10, 11, 12],
|
||||
[10, 12, 12], [11, 11, 11], [11, 11, 12], [11, 12, 12], [12, 12, 12]]
|
||||
end
|
||||
|
||||
it "yields [] when length is 0" do
|
||||
@array.repeated_combination(0).to_a.should == [[]] # one repeated_combination of length 0
|
||||
[].repeated_combination(0).to_a.should == [[]] # one repeated_combination of length 0
|
||||
end
|
||||
|
||||
it "yields nothing when the array is empty and num is non zero" do
|
||||
[].repeated_combination(5).to_a.should == [] # one repeated_combination of length 0
|
||||
end
|
||||
|
||||
it "yields a partition consisting of only singletons" do
|
||||
@array.repeated_combination(1).sort.to_a.should == [[10],[11],[12]]
|
||||
end
|
||||
|
||||
it "accepts sizes larger than the original array" do
|
||||
@array.repeated_combination(4).to_a.sort.should ==
|
||||
[[10, 10, 10, 10], [10, 10, 10, 11], [10, 10, 10, 12],
|
||||
[10, 10, 11, 11], [10, 10, 11, 12], [10, 10, 12, 12],
|
||||
[10, 11, 11, 11], [10, 11, 11, 12], [10, 11, 12, 12],
|
||||
[10, 12, 12, 12], [11, 11, 11, 11], [11, 11, 11, 12],
|
||||
[11, 11, 12, 12], [11, 12, 12, 12], [12, 12, 12, 12]]
|
||||
end
|
||||
|
||||
it "generates from a defensive copy, ignoring mutations" do
|
||||
accum = []
|
||||
@array.repeated_combination(2) do |x|
|
||||
accum << x
|
||||
@array[0] = 1
|
||||
end
|
||||
accum.sort.should == [[10, 10], [10, 11], [10, 12], [11, 11], [11, 12], [12, 12]]
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "returns 0 when the combination_size is < 0" do
|
||||
@array.repeated_combination(-1).size.should == 0
|
||||
[].repeated_combination(-2).size.should == 0
|
||||
end
|
||||
|
||||
it "returns 1 when the combination_size is 0" do
|
||||
@array.repeated_combination(0).size.should == 1
|
||||
[].repeated_combination(0).size.should == 1
|
||||
end
|
||||
|
||||
it "returns the binomial coeficient between combination_size and array size + combination_size -1" do
|
||||
@array.repeated_combination(5).size.should == 21
|
||||
@array.repeated_combination(4).size.should == 15
|
||||
@array.repeated_combination(3).size.should == 10
|
||||
@array.repeated_combination(2).size.should == 6
|
||||
@array.repeated_combination(1).size.should == 3
|
||||
@array.repeated_combination(0).size.should == 1
|
||||
[].repeated_combination(0).size.should == 1
|
||||
[].repeated_combination(1).size.should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
94
spec/ruby/core/array/repeated_permutation_spec.rb
Normal file
94
spec/ruby/core/array/repeated_permutation_spec.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
|
||||
describe "Array#repeated_permutation" do
|
||||
|
||||
before :each do
|
||||
@numbers = [10, 11, 12]
|
||||
@permutations = [[10, 10], [10, 11], [10, 12], [11, 10], [11, 11], [11, 12], [12, 10], [12, 11], [12, 12]]
|
||||
end
|
||||
|
||||
it "returns an Enumerator of all repeated permutations of given length when called without a block" do
|
||||
enum = @numbers.repeated_permutation(2)
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
enum.to_a.sort.should == @permutations
|
||||
end
|
||||
|
||||
it "yields all repeated_permutations to the block then returns self when called with block but no arguments" do
|
||||
yielded = []
|
||||
@numbers.repeated_permutation(2) {|n| yielded << n}.should equal(@numbers)
|
||||
yielded.sort.should == @permutations
|
||||
end
|
||||
|
||||
it "yields the empty repeated_permutation ([[]]) when the given length is 0" do
|
||||
@numbers.repeated_permutation(0).to_a.should == [[]]
|
||||
[].repeated_permutation(0).to_a.should == [[]]
|
||||
end
|
||||
|
||||
it "does not yield when called on an empty Array with a nonzero argument" do
|
||||
[].repeated_permutation(10).to_a.should == []
|
||||
end
|
||||
|
||||
it "handles duplicate elements correctly" do
|
||||
@numbers[-1] = 10
|
||||
@numbers.repeated_permutation(2).sort.should ==
|
||||
[[10, 10], [10, 10], [10, 10], [10, 10], [10, 11], [10, 11], [11, 10], [11, 10], [11, 11]]
|
||||
end
|
||||
|
||||
it "truncates Float arguments" do
|
||||
@numbers.repeated_permutation(3.7).to_a.sort.should ==
|
||||
@numbers.repeated_permutation(3).to_a.sort
|
||||
end
|
||||
|
||||
it "returns an Enumerator which works as expected even when the array was modified" do
|
||||
@numbers.shift
|
||||
enum = @numbers.repeated_permutation(2)
|
||||
@numbers.unshift 10
|
||||
enum.to_a.sort.should == @permutations
|
||||
end
|
||||
|
||||
it "allows permutations larger than the number of elements" do
|
||||
[1,2].repeated_permutation(3).sort.should ==
|
||||
[[1, 1, 1], [1, 1, 2], [1, 2, 1],
|
||||
[1, 2, 2], [2, 1, 1], [2, 1, 2],
|
||||
[2, 2, 1], [2, 2, 2]]
|
||||
end
|
||||
|
||||
it "generates from a defensive copy, ignoring mutations" do
|
||||
accum = []
|
||||
ary = [1,2]
|
||||
ary.repeated_permutation(3) do |x|
|
||||
accum << x
|
||||
ary[0] = 5
|
||||
end
|
||||
|
||||
accum.sort.should ==
|
||||
[[1, 1, 1], [1, 1, 2], [1, 2, 1],
|
||||
[1, 2, 2], [2, 1, 1], [2, 1, 2],
|
||||
[2, 2, 1], [2, 2, 2]]
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "returns 0 when combination_size is < 0" do
|
||||
@numbers.repeated_permutation(-1).size.should == 0
|
||||
[].repeated_permutation(-1).size.should == 0
|
||||
end
|
||||
|
||||
it "returns array size ** combination_size" do
|
||||
@numbers.repeated_permutation(4).size.should == 81
|
||||
@numbers.repeated_permutation(3).size.should == 27
|
||||
@numbers.repeated_permutation(2).size.should == 9
|
||||
@numbers.repeated_permutation(1).size.should == 3
|
||||
@numbers.repeated_permutation(0).size.should == 1
|
||||
[].repeated_permutation(4).size.should == 0
|
||||
[].repeated_permutation(3).size.should == 0
|
||||
[].repeated_permutation(2).size.should == 0
|
||||
[].repeated_permutation(1).size.should == 0
|
||||
[].repeated_permutation(0).size.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
7
spec/ruby/core/array/replace_spec.rb
Normal file
7
spec/ruby/core/array/replace_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/replace', __FILE__)
|
||||
|
||||
describe "Array#replace" do
|
||||
it_behaves_like(:array_replace, :replace)
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue