1# Tests the various random deviates 2 3use strict; 4use warnings; 5 6use Test::More 'tests' => 950; 7 8my @WARN; 9BEGIN { 10 # Warning signal handler 11 $SIG{__WARN__} = sub { push(@WARN, @_); }; 12} 13 14use_ok('Math::Random::MT::Auto', qw(exponential erlang poisson 15 binomial shuffle)); 16can_ok('Math::Random::MT::Auto', qw(exponential erlang poisson 17 binomial shuffle)); 18can_ok('main', qw(exponential erlang poisson 19 binomial shuffle)); 20 21# Check for warnings 22if (! ok(! @WARN, 'Acquired seed data')) { 23 diag('Seed warnings: ' . join(' | ', @WARN)); 24} 25undef(@WARN); 26 27my (@rn); 28 29# Test several values from exponential() 30undef(@rn); 31for my $ii (0 .. 9) { 32 eval { $rn[$ii] = exponential(); }; 33 ok(! $@, 'exponential() died: ' . $@); 34 ok(defined($rn[$ii]), 'Got a random number'); 35 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 36 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 37 for my $jj (0 .. $ii-1) { 38 ok($rn[$jj] != $rn[$ii], 'Randomized'); 39 } 40} 41 42# Test several values from erlang() for small order 43undef(@rn); 44for my $ii (0 .. 9) { 45 eval { $rn[$ii] = erlang(3); }; 46 ok(! $@, 'erlang(3) died: ' . $@); 47 ok(defined($rn[$ii]), 'Got a random number'); 48 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 49 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 50 for my $jj (0 .. $ii-1) { 51 ok($rn[$jj] != $rn[$ii], 'Randomized'); 52 } 53} 54 55# Test several values from erlang() for larger order 56undef(@rn); 57for my $ii (0 .. 9) { 58 eval { $rn[$ii] = erlang(10); }; 59 ok(! $@, 'erlang(10) died: ' . $@); 60 ok(defined($rn[$ii]), 'Got a random number'); 61 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 62 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 63 for my $jj (0 .. $ii-1) { 64 ok($rn[$jj] != $rn[$ii], 'Randomized'); 65 } 66} 67 68# Test several values from poisson() for small order 69undef(@rn); 70for my $ii (0 .. 9) { 71 eval { $rn[$ii] = poisson(3); }; 72 ok(! $@, 'poisson(3) died: ' . $@); 73 ok(defined($rn[$ii]), 'Got a random number'); 74 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 75 ok(int($rn[$ii]) == $rn[$ii] && 76 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 77} 78 79# Test several values from poisson() for large order 80undef(@rn); 81for my $ii (0 .. 9) { 82 eval { $rn[$ii] = poisson(30); }; 83 ok(! $@, 'poisson(30) died: ' . $@); 84 ok(defined($rn[$ii]), 'Got a random number'); 85 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 86 ok(int($rn[$ii]) == $rn[$ii] && 87 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 88} 89 90# Test several values from binomial() for small trial count 91undef(@rn); 92for my $ii (0 .. 9) { 93 eval { $rn[$ii] = binomial(0.5, 15); }; 94 ok(! $@, 'binomial(0.5, 15) died: ' . $@); 95 ok(defined($rn[$ii]), 'Got a random number'); 96 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 97 ok(int($rn[$ii]) == $rn[$ii] && 98 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 99} 100 101# Test several values from binomial() for small mean 102undef(@rn); 103for my $ii (0 .. 9) { 104 eval { $rn[$ii] = binomial(0.01, 30); }; 105 ok(! $@, 'binomial(0.01, 30) died: ' . $@); 106 ok(defined($rn[$ii]), 'Got a random number'); 107 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 108 ok(int($rn[$ii]) == $rn[$ii] && 109 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 110} 111 112# Test several values from binomial() 113undef(@rn); 114for my $ii (0 .. 9) { 115 eval { $rn[$ii] = binomial(0.8, 50); }; 116 ok(! $@, 'binomial(0.8, 50) died: ' . $@); 117 ok(defined($rn[$ii]), 'Got a random number'); 118 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 119 ok(int($rn[$ii]) == $rn[$ii] && 120 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 121} 122 123# Test of shuffle() 124my @data = ( 125 [ 'xyz' ], 'abc', 1, 0.0, 1e-3, { 'q' => 42 }, sub { return (99); } 126); 127my $shuf; 128eval { $shuf = shuffle(@data); }; 129ok(! $@, 'shuffle okay'); 130for my $x (@$shuf) { 131 my $found = 0; 132 for my $y (@data) { 133 if (ref($x) eq 'CODE') { 134 if (ref($y) eq 'CODE') { 135 pass('shuffle - code ref okay'); 136 $found = 1; 137 last; 138 } 139 } elsif (ref($x) eq 'ARRAY') { 140 if (ref($y) eq 'ARRAY') { 141 is_deeply($x, $y, 'shuffle - array okay'); 142 $found = 1; 143 last; 144 } 145 } elsif (ref($x) eq 'HASH') { 146 if (ref($y) eq 'HASH') { 147 is_deeply($x, $y, 'shuffle - hash okay'); 148 $found = 1; 149 last; 150 } 151 } elsif (Scalar::Util::looks_like_number($x)) { 152 if (Scalar::Util::looks_like_number($y) && ($x == $y)) { 153 pass("shuffle - $x okay"); 154 $found = 1; 155 last; 156 } 157 } elsif (! ref($y) && ! Scalar::Util::looks_like_number($y) && ($x eq $y)) { 158 pass("shuffle - $x okay"); 159 $found = 1; 160 last; 161 } 162 } 163 if (! $found) { 164 fail('shuffle element not found'); 165 } 166} 167my @shuf; 168eval { @shuf = shuffle(@data); }; 169ok(! $@, 'shuffle okay'); 170for my $x (@shuf) { 171 my $found = 0; 172 for my $y (@data) { 173 if (ref($x) eq 'CODE') { 174 if (ref($y) eq 'CODE') { 175 pass('shuffle - code ref okay'); 176 $found = 1; 177 last; 178 } 179 } elsif (ref($x) eq 'ARRAY') { 180 if (ref($y) eq 'ARRAY') { 181 is_deeply($x, $y, 'shuffle - array okay'); 182 $found = 1; 183 last; 184 } 185 } elsif (ref($x) eq 'HASH') { 186 if (ref($y) eq 'HASH') { 187 is_deeply($x, $y, 'shuffle - hash okay'); 188 $found = 1; 189 last; 190 } 191 } elsif (Scalar::Util::looks_like_number($x)) { 192 if (Scalar::Util::looks_like_number($y) && ($x == $y)) { 193 pass("shuffle - $x okay"); 194 $found = 1; 195 last; 196 } 197 } elsif (! ref($y) && ! Scalar::Util::looks_like_number($y) && ($x eq $y)) { 198 pass("shuffle - $x okay"); 199 $found = 1; 200 last; 201 } 202 } 203 if (! $found) { 204 fail('shuffle element not found'); 205 } 206} 207eval { shuffle(\@data); }; 208ok(! $@, 'shuffle okay'); 209for my $x (@data) { 210 my $found = 0; 211 for my $y (@data) { 212 if (ref($x) eq 'CODE') { 213 if (ref($y) eq 'CODE') { 214 pass('shuffle - code ref okay'); 215 $found = 1; 216 last; 217 } 218 } elsif (ref($x) eq 'ARRAY') { 219 if (ref($y) eq 'ARRAY') { 220 is_deeply($x, $y, 'shuffle - array okay'); 221 $found = 1; 222 last; 223 } 224 } elsif (ref($x) eq 'HASH') { 225 if (ref($y) eq 'HASH') { 226 is_deeply($x, $y, 'shuffle - hash okay'); 227 $found = 1; 228 last; 229 } 230 } elsif (Scalar::Util::looks_like_number($x)) { 231 if (Scalar::Util::looks_like_number($y) && ($x == $y)) { 232 pass("shuffle - $x okay"); 233 $found = 1; 234 last; 235 } 236 } elsif (! ref($y) && ! Scalar::Util::looks_like_number($y) && ($x eq $y)) { 237 pass("shuffle - $x okay"); 238 $found = 1; 239 last; 240 } 241 } 242 if (! $found) { 243 fail('shuffle element not found'); 244 } 245} 246 247 248# Create PRNG object 249my $prng; 250eval { $prng = Math::Random::MT::Auto->new(); }; 251if (! ok(! $@, '->new works')) { 252 diag('->new died: ' . $@); 253} 254isa_ok($prng, 'Math::Random::MT::Auto'); 255can_ok($prng, qw(rand irand gaussian exponential erlang poisson binomial 256 shuffle get_seed set_seed get_state set_state)); 257 258# Check for warnings 259if (! ok(! @WARN, 'Acquired seed data')) { 260 diag('Seed warnings: ' . join(' | ', @WARN)); 261} 262undef(@WARN); 263 264# Test several values from exponential() 265undef(@rn); 266for my $ii (0 .. 9) { 267 eval { $rn[$ii] = $prng->exponential(2); }; 268 ok(! $@, '$prng->exponential() died: ' . $@); 269 ok(defined($rn[$ii]), 'Got a random number'); 270 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 271 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 272 for my $jj (0 .. $ii-1) { 273 ok($rn[$jj] != $rn[$ii], 'Randomized'); 274 } 275} 276 277# Test several values from erlang() for small order 278undef(@rn); 279for my $ii (0 .. 9) { 280 eval { $rn[$ii] = $prng->erlang(3); }; 281 ok(! $@, '$prng->erlang(3) died: ' . $@); 282 ok(defined($rn[$ii]), 'Got a random number'); 283 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 284 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 285 for my $jj (0 .. $ii-1) { 286 ok($rn[$jj] != $rn[$ii], 'Randomized'); 287 } 288} 289 290# Test several values from erlang() for larger order 291undef(@rn); 292for my $ii (0 .. 9) { 293 eval { $rn[$ii] = $prng->erlang(10); }; 294 ok(! $@, '$prng->erlang(10) died: ' . $@); 295 ok(defined($rn[$ii]), 'Got a random number'); 296 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 297 ok($rn[$ii] > 0.0, 'Positive: ' . $rn[$ii]); 298 for my $jj (0 .. $ii-1) { 299 ok($rn[$jj] != $rn[$ii], 'Randomized'); 300 } 301} 302 303# Test several values from poisson() for small order 304undef(@rn); 305for my $ii (0 .. 9) { 306 eval { $rn[$ii] = $prng->poisson(3); }; 307 ok(! $@, '$prng->poisson(3) died: ' . $@); 308 ok(defined($rn[$ii]), 'Got a random number'); 309 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 310 ok(int($rn[$ii]) == $rn[$ii] && 311 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 312} 313 314# Test several values from poisson() for large order 315undef(@rn); 316for my $ii (0 .. 9) { 317 eval { $rn[$ii] = $prng->poisson(30); }; 318 ok(! $@, '$prng->poisson(30) died: ' . $@); 319 ok(defined($rn[$ii]), 'Got a random number'); 320 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 321 ok(int($rn[$ii]) == $rn[$ii] && 322 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 323} 324 325# Test several values from binomial() for small trial count 326undef(@rn); 327for my $ii (0 .. 9) { 328 eval { $rn[$ii] = $prng->binomial(0.5, 15); }; 329 ok(! $@, '$prng->binomial(0.5, 15) died: ' . $@); 330 ok(defined($rn[$ii]), 'Got a random number'); 331 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 332 ok(int($rn[$ii]) == $rn[$ii] && 333 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 334} 335 336# Test several values from binomial() for small mean 337undef(@rn); 338for my $ii (0 .. 9) { 339 eval { $rn[$ii] = $prng->binomial(0.01, 30); }; 340 ok(! $@, '$prng->binomial(0.01, 30) died: ' . $@); 341 ok(defined($rn[$ii]), 'Got a random number'); 342 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 343 ok(int($rn[$ii]) == $rn[$ii] && 344 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 345} 346 347# Test several values from binomial() 348undef(@rn); 349for my $ii (0 .. 9) { 350 eval { $rn[$ii] = $prng->binomial(0.8, 50); }; 351 ok(! $@, '$prng->binomial(0.8, 50) died: ' . $@); 352 ok(defined($rn[$ii]), 'Got a random number'); 353 ok(Scalar::Util::looks_like_number($rn[$ii]), 'Is a number: ' . $rn[$ii]); 354 ok(int($rn[$ii]) == $rn[$ii] && 355 $rn[$ii] >= 0, 'Non-neg integer: ' . $rn[$ii]); 356} 357 358# Test of shuffle() 359eval { $shuf = $prng->shuffle($shuf); }; 360ok(! $@, '$prng->shuffle okay'); 361for my $x (@$shuf) { 362 my $found = 0; 363 for my $y (@data) { 364 if (ref($x) eq 'CODE') { 365 if (ref($y) eq 'CODE') { 366 pass('$prng->shuffle - code ref okay'); 367 $found = 1; 368 last; 369 } 370 } elsif (ref($x) eq 'ARRAY') { 371 if (ref($y) eq 'ARRAY') { 372 is_deeply($x, $y, '$prng->shuffle - array okay'); 373 $found = 1; 374 last; 375 } 376 } elsif (ref($x) eq 'HASH') { 377 if (ref($y) eq 'HASH') { 378 is_deeply($x, $y, '$prng->shuffle - hash okay'); 379 $found = 1; 380 last; 381 } 382 } elsif (Scalar::Util::looks_like_number($x)) { 383 if (Scalar::Util::looks_like_number($y) && ($x == $y)) { 384 pass("\$prng->shuffle - $x okay"); 385 $found = 1; 386 last; 387 } 388 } elsif (! ref($y) && ! Scalar::Util::looks_like_number($y) && ($x eq $y)) { 389 pass("\$prng->shuffle - $x okay"); 390 $found = 1; 391 last; 392 } 393 } 394 if (! $found) { 395 fail('shuffle element not found'); 396 } 397} 398 399exit(0); 400 401# EOF 402