1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Array#sample" do
it "samples evenly" do
ary = [0, 1, 2, 3]
3.times do |i|
counts = [0, 0, 0, 0]
4000.times do
counts[ary.sample(3)[i]] += 1
end
counts.each do |count|
(800..1200).should include(count)
end
end
end
it "returns nil for an empty Array" do
[].sample.should be_nil
end
it "returns a single value when not passed a count" do
[4].sample.should equal(4)
end
it "returns an empty Array when passed zero" do
[4].sample(0).should == []
end
it "returns an Array of elements when passed a count" do
[1, 2, 3, 4].sample(3).should be_an_instance_of(Array)
end
it "returns elements from the Array" do
array = [1, 2, 3, 4]
array.sample(3).all? { |x| array.should include(x) }
end
it "returns at most the number of elements in the Array" do
array = [1, 2, 3, 4]
result = array.sample(20)
result.size.should == 4
end
it "does not return the same value if the Array has unique values" do
array = [1, 2, 3, 4]
result = array.sample(20)
result.sort.should == array
end
it "may return the same value if the array is not unique" do
[4, 4].sample(2).should == [4,4]
end
it "calls #to_int to convert the count when passed an Object" do
[1, 2, 3, 4].sample(mock_int(2)).size.should == 2
end
it "raises ArgumentError when passed a negative count" do
lambda { [1, 2].sample(-1) }.should raise_error(ArgumentError)
end
it "does not return subclass instances with Array subclass" do
ArraySpecs::MyArray[1, 2, 3].sample(2).should be_an_instance_of(Array)
end
describe "with options" do
it "calls #to_hash to convert the passed Object" do
obj = mock("array_sample")
obj.should_receive(:to_hash).and_return({})
obj.should_not_receive(:to_int)
[1, 2].sample(obj).should be_an_instance_of(Fixnum)
end
it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
count = mock("array_sample_count")
count.should_receive(:to_int).and_return(2)
options = mock("array_sample_options")
options.should_receive(:to_hash).and_return({})
[1, 2].sample(count, options).size.should == 2
end
it "calls #rand on the Object passed by the :random key in the arguments Hash" do
obj = mock("array_sample_random")
obj.should_receive(:rand).and_return(0.5)
[1, 2].sample(random: obj).should be_an_instance_of(Fixnum)
end
it "raises a NoMethodError if an object passed for the RNG does not define #rand" do
obj = BasicObject.new
lambda { [1, 2].sample(random: obj) }.should raise_error(NoMethodError)
end
describe "when the object returned by #rand is a Fixnum" do
it "uses the fixnum as index" do
random = mock("array_sample_random_ret")
random.should_receive(:rand).and_return(0)
[1, 2].sample(random: random).should == 1
random = mock("array_sample_random_ret")
random.should_receive(:rand).and_return(1)
[1, 2].sample(random: random).should == 2
end
it "raises a RangeError if the value is less than zero" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(-1)
lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
it "raises a RangeError if the value is equal to the Array size" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(2)
lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
end
end
describe "when the object returned by #rand is not a Fixnum but responds to #to_int" do
it "calls #to_int on the Object" do
value = mock("array_sample_random_value")
value.should_receive(:to_int).and_return(1)
random = mock("array_sample_random")
random.should_receive(:rand).and_return(value)
[1, 2].sample(random: random).should == 2
end
it "raises a RangeError if the value is less than zero" do
value = mock("array_sample_random_value")
value.should_receive(:to_int).and_return(-1)
random = mock("array_sample_random")
random.should_receive(:rand).and_return(value)
lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
it "raises a RangeError if the value is equal to the Array size" do
value = mock("array_sample_random_value")
value.should_receive(:to_int).and_return(2)
random = mock("array_sample_random")
random.should_receive(:rand).and_return(value)
lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
end
end
|