# frozen_string_literal: false require 'test/unit' class TestRand < Test::Unit::TestCase def assert_random_int(m, init = 0, iterate: 5) srand(init) rnds = [Random.new(init)] rnds2 = [rnds[0].dup] rnds3 = [rnds[0].dup] iterate.times do |i| w = rand(m) rnds.each do |rnd| assert_equal(w, rnd.rand(m)) end rnds2.each do |rnd| r=rnd.rand(i...(m+i)) assert_equal(w+i, r) end rnds3.each do |rnd| r=rnd.rand(i..(m+i-1)) assert_equal(w+i, r) end rnds << Marshal.load(Marshal.dump(rnds[-1])) rnds2 << Marshal.load(Marshal.dump(rnds2[-1])) end end def test_mt assert_random_int(0x100000000, 0x00000456_00000345_00000234_00000123) end def test_0x3fffffff assert_random_int(0x3fffffff) end def test_0x40000000 assert_random_int(0x40000000) end def test_0x40000001 assert_random_int(0x40000001) end def test_0xffffffff assert_random_int(0xffffffff) end def test_0x100000000 assert_random_int(0x100000000) end def test_0x100000001 assert_random_int(0x100000001) end def test_rand_0x100000000 assert_random_int(0x100000001, 311702798) end def test_0x1000000000000 assert_random_int(0x1000000000000) end def test_0x1000000000001 assert_random_int(0x1000000000001) end def test_0x3fffffffffffffff assert_random_int(0x3fffffffffffffff) end def test_0x4000000000000000 assert_random_int(0x4000000000000000) end def test_0x4000000000000001 assert_random_int(0x4000000000000001) end def test_0x10000000000 assert_random_int(0x10000000000, 3) end def test_0x10000 assert_random_int(0x10000) end def assert_same_numbers(type, *nums) nums.each do |n| assert_instance_of(type, n) end x = nums.shift nums.each do |n| assert_equal(x, n) end x end def test_types o = Object.new class << o def to_int; 100; end def class; Integer; end end srand(0) nums = [100.0, (2**100).to_f, (2**100), o, o, o].map do |m| k = Integer assert_kind_of(k, x = rand(m), m.inspect) [m, k, x] end assert_kind_of(Integer, rand(-(2**100).to_f)) srand(0) rnd = Random.new(0) rnd2 = Random.new(0) nums.each do |m, k, x| assert_same_numbers(m.class, Random.rand(m), rnd.rand(m), rnd2.rand(m)) end end def test_srand srand assert_kind_of(Integer, rand(2)) assert_kind_of(Integer, Random.new.rand(2)) srand(2**100) rnd = Random.new(2**100) r = 3.times.map do assert_same_numbers(Integer, rand(0x100000000), rnd.rand(0x100000000)) end srand(2**100) r.each do |n| assert_same_numbers(Integer, n, rand(0x100000000)) end end def test_shuffle srand(0) result = [*1..5].shuffle assert_equal([*1..5], result.sort) assert_equal(result, [*1..5].shuffle(random: Random.new(0))) end def test_big_seed assert_random_int(0x100000000, 2**1000000-1) end def test_random_gc r = Random.new(0) 3.times do assert_kind_of(Integer, r.rand(0x100000000)) end GC.start 3.times do assert_kind_of(Integer, r.rand(0x100000000)) end end def test_random_type_error assert_raise(TypeError) { Random.new(Object.new) } assert_raise(TypeError) { Random.new(0).rand(Object.new) } end def test_random_argument_error r = Random.new(0) assert_raise(ArgumentError) { r.rand(0, 0) } assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1) } assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1.0) } assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(0) } assert_equal(0, r.rand(1), '[ruby-dev:39166]') assert_equal(0, r.rand(0...1), '[ruby-dev:39166]') assert_equal(0, r.rand(0..0), '[ruby-dev:39166]') assert_equal(0.0, r.rand(0.0..0.0), '[ruby-dev:39166]') assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0...0) } assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0..-1) } assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0.0...0.0) } assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0.0...-0.1) } bug3027 = '[ruby-core:29075]' assert_raise(ArgumentError, bug3027) { r.rand(nil) } end def test_random_seed assert_equal(0, Random.new(0).seed) assert_equal(0x100000000, Random.new(0x100000000).seed) assert_equal(2**100, Random.new(2**100).seed) end def test_random_dup r1 = Random.new(0) r2 = r1.dup 3.times do assert_same_numbers(Integer, r1.rand(0x100000000), r2.rand(0x100000000)) end r2 = r1.dup 3.times do assert_same_numbers(Integer, r1.rand(0x100000000), r2.rand(0x100000000)) end end def test_random_state state = <, 15) end end