1require_relative '../../spec_helper'
2
3describe "Random.rand" do
4  it "returns a Float if no max argument is passed" do
5    Random.rand.should be_kind_of(Float)
6  end
7
8  it "returns a Float >= 0 if no max argument is passed" do
9    floats = 200.times.map { Random.rand }
10    floats.min.should >= 0
11  end
12
13  it "returns a Float < 1 if no max argument is passed" do
14    floats = 200.times.map { Random.rand }
15    floats.max.should < 1
16  end
17
18  it "returns the same sequence for a given seed if no max argument is passed" do
19    Random.srand 33
20    floats_a = 20.times.map { Random.rand }
21    Random.srand 33
22    floats_b = 20.times.map { Random.rand }
23    floats_a.should == floats_b
24  end
25
26  it "returns an Integer if an Integer argument is passed" do
27    Random.rand(20).should be_kind_of(Integer)
28  end
29
30  it "returns an Integer >= 0 if an Integer argument is passed" do
31    ints = 200.times.map { Random.rand(34) }
32    ints.min.should >= 0
33  end
34
35  it "returns an Integer < the max argument if an Integer argument is passed" do
36    ints = 200.times.map { Random.rand(55) }
37    ints.max.should < 55
38  end
39
40  it "returns the same sequence for a given seed if an Integer argument is passed" do
41    Random.srand 33
42    floats_a = 20.times.map { Random.rand(90) }
43    Random.srand 33
44    floats_b = 20.times.map { Random.rand(90) }
45    floats_a.should == floats_b
46  end
47
48  it "coerces arguments to Integers with #to_int" do
49    obj = mock_numeric('int')
50    obj.should_receive(:to_int).and_return(99)
51    Random.rand(obj).should be_kind_of(Integer)
52  end
53end
54
55describe "Random#rand with Fixnum" do
56  it "returns an Integer" do
57    Random.new.rand(20).should be_an_instance_of(Fixnum)
58  end
59
60  it "returns a Fixnum greater than or equal to 0" do
61    prng = Random.new
62    ints = 20.times.map { prng.rand(5) }
63    ints.min.should >= 0
64  end
65
66  it "returns a Fixnum less than the argument" do
67    prng = Random.new
68    ints = 20.times.map { prng.rand(5) }
69    ints.max.should <= 4
70  end
71
72  it "returns the same sequence for a given seed" do
73    prng = Random.new 33
74    a = 20.times.map { prng.rand(90) }
75    prng = Random.new 33
76    b = 20.times.map { prng.rand(90) }
77    a.should == b
78  end
79
80  it "eventually returns all possible values" do
81    prng = Random.new 33
82    100.times.map{ prng.rand(10) }.uniq.sort.should == (0...10).to_a
83  end
84
85  it "raises an ArgumentError when the argument is 0" do
86    lambda do
87      Random.new.rand(0)
88    end.should raise_error(ArgumentError)
89  end
90
91  it "raises an ArgumentError when the argument is negative" do
92    lambda do
93      Random.new.rand(-12)
94    end.should raise_error(ArgumentError)
95  end
96end
97
98describe "Random#rand with Bignum" do
99  it "typically returns a Bignum" do
100    rnd = Random.new(1)
101    10.times.map{ rnd.rand(bignum_value*2) }.max.should be_an_instance_of(Bignum)
102  end
103
104  it "returns a Bignum greater than or equal to 0" do
105    prng = Random.new
106    bigs = 20.times.map { prng.rand(bignum_value) }
107    bigs.min.should >= 0
108  end
109
110  it "returns a Bignum less than the argument" do
111    prng = Random.new
112    bigs = 20.times.map { prng.rand(bignum_value) }
113    bigs.max.should < bignum_value
114  end
115
116  it "returns the same sequence for a given seed" do
117    prng = Random.new 33
118    a = 20.times.map { prng.rand(bignum_value) }
119    prng = Random.new 33
120    b = 20.times.map { prng.rand(bignum_value) }
121    a.should == b
122  end
123
124  it "raises an ArgumentError when the argument is negative" do
125    lambda do
126      Random.new.rand(-bignum_value)
127    end.should raise_error(ArgumentError)
128  end
129end
130
131describe "Random#rand with Float" do
132  it "returns a Float" do
133    Random.new.rand(20.43).should be_an_instance_of(Float)
134  end
135
136  it "returns a Float greater than or equal to 0.0" do
137    prng = Random.new
138    floats = 20.times.map { prng.rand(5.2) }
139    floats.min.should >= 0.0
140  end
141
142  it "returns a Float less than the argument" do
143    prng = Random.new
144    floats = 20.times.map { prng.rand(4.30) }
145    floats.max.should < 4.30
146  end
147
148  it "returns the same sequence for a given seed" do
149    prng = Random.new 33
150    a = 20.times.map { prng.rand(89.2928) }
151    prng = Random.new 33
152    b = 20.times.map { prng.rand(89.2928) }
153    a.should == b
154  end
155
156  it "raises an ArgumentError when the argument is negative" do
157    lambda do
158      Random.new.rand(-1.234567)
159    end.should raise_error(ArgumentError)
160  end
161end
162
163describe "Random#rand with Range" do
164  it "returns an element from the Range" do
165    Random.new.rand(20..43).should be_an_instance_of(Fixnum)
166  end
167
168  it "returns an object that is a member of the Range" do
169    prng = Random.new
170    r = 20..30
171    20.times { r.member?(prng.rand(r)).should be_true }
172  end
173
174  it "works with inclusive ranges" do
175    prng = Random.new 33
176    r = 3..5
177    40.times.map { prng.rand(r) }.uniq.sort.should == [3,4,5]
178  end
179
180  it "works with exclusive ranges" do
181    prng = Random.new 33
182    r = 3...5
183    20.times.map { prng.rand(r) }.uniq.sort.should == [3,4]
184  end
185
186  it "returns the same sequence for a given seed" do
187    prng = Random.new 33
188    a = 20.times.map { prng.rand(76890.028..800000.00) }
189    prng = Random.new 33
190    b = 20.times.map { prng.rand(76890.028..800000.00) }
191    a.should == b
192  end
193
194  it "eventually returns all possible values" do
195    prng = Random.new 33
196    100.times.map{ prng.rand(10..20) }.uniq.sort.should == (10..20).to_a
197    100.times.map{ prng.rand(10...20) }.uniq.sort.should == (10...20).to_a
198  end
199
200  it "considers Integers as Floats if one end point is a float" do
201    Random.new(42).rand(0.0..1).should be_kind_of(Float)
202    Random.new(42).rand(0..1.0).should be_kind_of(Float)
203  end
204
205  it "raises an ArgumentError when the startpoint lacks #+ and #- methods" do
206    lambda do
207      Random.new.rand(Object.new..67)
208    end.should raise_error(ArgumentError)
209  end
210
211  it "raises an ArgumentError when the endpoint lacks #+ and #- methods" do
212    lambda do
213      Random.new.rand(68..Object.new)
214    end.should raise_error(ArgumentError)
215  end
216end
217