1eac174f2Safresh1# -*- mode: perl; -*- 2b8851fccSafresh1 3b8851fccSafresh1use strict; 4b8851fccSafresh1use warnings; 5b8851fccSafresh1 6*3d61058aSafresh1use Test::More tests => 126; 7b8851fccSafresh1 8*3d61058aSafresh1# Test Math::BigInt->config(), Math::BigFloat->config(), and 9*3d61058aSafresh1# Math::BigRat->config(). 10b8851fccSafresh1 11b8851fccSafresh1use Math::BigInt lib => 'Calc'; 12b8851fccSafresh1use Math::BigFloat; 13*3d61058aSafresh1use Math::BigRat; 14b8851fccSafresh1 15b8851fccSafresh1my $mbi = 'Math::BigInt'; 16b8851fccSafresh1my $mbf = 'Math::BigFloat'; 17*3d61058aSafresh1my $mbr = 'Math::BigRat'; 18b8851fccSafresh1 19*3d61058aSafresh1my @classes = ($mbi, $mbf, $mbr); 20*3d61058aSafresh1 21*3d61058aSafresh1# Default configuration. 22*3d61058aSafresh1 23*3d61058aSafresh1my %defaults = ( 24*3d61058aSafresh1 'accuracy' => undef, 25*3d61058aSafresh1 'precision' => undef, 26*3d61058aSafresh1 'round_mode' => 'even', 27*3d61058aSafresh1 'div_scale' => 40, 28*3d61058aSafresh1 'trap_inf' => 0, 29*3d61058aSafresh1 'trap_nan' => 0, 30*3d61058aSafresh1 'upgrade' => undef, 31*3d61058aSafresh1 'downgrade' => undef, 32*3d61058aSafresh1 'lib' => 'Math::BigInt::Calc', 33*3d61058aSafresh1 'lib_version' => $Math::BigInt::Calc::VERSION, 34*3d61058aSafresh1); 35b46d8ef2Safresh1 36b8851fccSafresh1############################################################################## 37*3d61058aSafresh1# Test config() as a getter. 38b8851fccSafresh1 39*3d61058aSafresh1for my $class (@classes) { 40b8851fccSafresh1 41*3d61058aSafresh1 note <<"EOF"; 42b8851fccSafresh1 43*3d61058aSafresh1Verify that $class->config("key") works. 44b46d8ef2Safresh1 45*3d61058aSafresh1EOF 46*3d61058aSafresh1 47*3d61058aSafresh1 can_ok($class, 'config'); 48*3d61058aSafresh1 49*3d61058aSafresh1 my %table = (%defaults, 'class' => $class); 50*3d61058aSafresh1 51*3d61058aSafresh1 # Test getting via the new style $class->config($key). 52*3d61058aSafresh1 53*3d61058aSafresh1 subtest qq|New-style getter $class->config("\$key")| => sub { 54*3d61058aSafresh1 plan tests => scalar keys %table; 55*3d61058aSafresh1 56*3d61058aSafresh1 for my $key (sort keys %table) { 57*3d61058aSafresh1 my $val = $table{$key}; 58*3d61058aSafresh1 is($class->config($key), $val, qq|$class->config("$key")|); 59b46d8ef2Safresh1 } 60*3d61058aSafresh1 }; 61b46d8ef2Safresh1 62*3d61058aSafresh1 # Test getting via the old style $class->config()->{$key}, which is still 63b46d8ef2Safresh1 # supported: 64b46d8ef2Safresh1 65*3d61058aSafresh1 my $cfg = $class->config(); 66*3d61058aSafresh1 is(ref($cfg), 'HASH', "ref() of output from $class->config()"); 67b8851fccSafresh1 68*3d61058aSafresh1 subtest qq|Old-style getter $class->config()->{"\$key"}| => sub { 69*3d61058aSafresh1 plan tests => scalar keys %table; 70*3d61058aSafresh1 71*3d61058aSafresh1 for my $key (sort keys %table) { 72*3d61058aSafresh1 my $val = $table{$key}; 73*3d61058aSafresh1 is($cfg->{$key}, $val, qq|$class->config()->{$key}|); 74b46d8ef2Safresh1 } 75*3d61058aSafresh1 }; 76b8851fccSafresh1 77*3d61058aSafresh1 # Can set via hash ref? 78b8851fccSafresh1 79*3d61058aSafresh1 $cfg = $class->config({ trap_nan => 1 }); 80*3d61058aSafresh1 is($cfg->{trap_nan}, 1, 'can set "trap_nan" to 1 via hash ref'); 81*3d61058aSafresh1 82*3d61058aSafresh1 # Restore for later. 83*3d61058aSafresh1 84*3d61058aSafresh1 $cfg = $class->config({ trap_nan => 0 }); 85*3d61058aSafresh1 is($cfg->{trap_nan}, 0, 'can set "trap_nan" to 0 via hash ref'); 86b8851fccSafresh1} 87b8851fccSafresh1 88b8851fccSafresh1############################################################################## 89*3d61058aSafresh1# Test config() as a setter. 90b8851fccSafresh1 91*3d61058aSafresh1# Alternative configuration. All values should be different from the default 92*3d61058aSafresh1# configuration. 93b8851fccSafresh1 94b8851fccSafresh1my $test = { 95b8851fccSafresh1 accuracy => 2, 96b8851fccSafresh1 precision => 3, 97b8851fccSafresh1 round_mode => 'zero', 98b8851fccSafresh1 div_scale => '100', 99*3d61058aSafresh1 trap_inf => 1, 100*3d61058aSafresh1 trap_nan => 1, 101b8851fccSafresh1 upgrade => 'Math::BigInt::SomeClass', 102b8851fccSafresh1 downgrade => 'Math::BigInt::SomeClass', 103b8851fccSafresh1}; 104b8851fccSafresh1 105*3d61058aSafresh1for my $class (@classes) { 106b8851fccSafresh1 107*3d61058aSafresh1 note <<"EOF"; 108b8851fccSafresh1 109*3d61058aSafresh1Verify that $class->config("key" => value) works and that 110*3d61058aSafresh1it doesn't affect the configuration of other classes. 111b8851fccSafresh1 112*3d61058aSafresh1EOF 113b8851fccSafresh1 114*3d61058aSafresh1 for my $key (sort keys %$test) { 115*3d61058aSafresh1 116*3d61058aSafresh1 # Get the original value for restoring it later. 117*3d61058aSafresh1 118*3d61058aSafresh1 my $orig = $class->config($key); 119*3d61058aSafresh1 120*3d61058aSafresh1 # Try setting the new value. 121*3d61058aSafresh1 122*3d61058aSafresh1 eval { $class->config($key => $test->{$key}); }; 123*3d61058aSafresh1 die $@ if $@; 124*3d61058aSafresh1 125*3d61058aSafresh1 # Verify that the value was set correctly. 126*3d61058aSafresh1 127*3d61058aSafresh1 is($class->config($key), $test->{$key}, 128*3d61058aSafresh1 qq|$class->config("$key") set to $test->{$key}|); 129*3d61058aSafresh1 130*3d61058aSafresh1 # Verify that setting it in class $class didn't affect other classes. 131*3d61058aSafresh1 132*3d61058aSafresh1 for my $other (@classes) { 133*3d61058aSafresh1 next if $other eq $class; 134*3d61058aSafresh1 135*3d61058aSafresh1 isnt($other->config($key), $class->config($key), 136*3d61058aSafresh1 qq|$other->config("$key") isn't affected by setting | . 137*3d61058aSafresh1 qq|$class->config("$key")|); 138b8851fccSafresh1 } 139b8851fccSafresh1 140*3d61058aSafresh1 # Restore the value. 141b8851fccSafresh1 142*3d61058aSafresh1 $class->config($key => $orig); 143*3d61058aSafresh1 144*3d61058aSafresh1 # Verify that the value was restored. 145*3d61058aSafresh1 146*3d61058aSafresh1 is($class->config($key), $orig, 147*3d61058aSafresh1 qq|$class->config("$key") reset to | . 148*3d61058aSafresh1 (defined($orig) ? qq|"$orig"| : "undef")); 149*3d61058aSafresh1 } 150*3d61058aSafresh1} 151*3d61058aSafresh1 152*3d61058aSafresh1# Verify that setting via a hash doesn't modify the hash. 153*3d61058aSafresh1 154*3d61058aSafresh1# In the $test configuration, both accuracy and precision are defined, which 155*3d61058aSafresh1# won't work, so set one of them to undef. 156*3d61058aSafresh1 157*3d61058aSafresh1$test->{accuracy} = undef; 158*3d61058aSafresh1 159*3d61058aSafresh1for my $class (@classes) { 160*3d61058aSafresh1 161*3d61058aSafresh1 note <<"EOF"; 162*3d61058aSafresh1 163*3d61058aSafresh1Verify that $class->config({key1 => val1, key2 => val2, ...}) 164*3d61058aSafresh1doesn't modify the hash ref argument. 165*3d61058aSafresh1 166*3d61058aSafresh1EOF 167*3d61058aSafresh1 168*3d61058aSafresh1 subtest "Verify that $class->config(\$cfg) doesn't modify \$cfg" => sub { 169*3d61058aSafresh1 plan tests => 2 * keys %$test; 170*3d61058aSafresh1 171*3d61058aSafresh1 # Make copy of the configuration hash and use it as input to config(). 172*3d61058aSafresh1 173*3d61058aSafresh1 my $cfg = { %{ $test } }; 174*3d61058aSafresh1 eval { $class -> config($cfg); }; 175*3d61058aSafresh1 die $@ if $@; 176*3d61058aSafresh1 177*3d61058aSafresh1 # Verify that the configuration hash hasn't been modified. 178*3d61058aSafresh1 179*3d61058aSafresh1 for my $key (sort keys %$test) { 180*3d61058aSafresh1 ok(exists $cfg->{$key}, qq|existens of \$cfg->{"$key"}|); 181*3d61058aSafresh1 is($cfg->{$key}, $test->{$key}, qq|value of \$cfg->{"$key"}|); 182*3d61058aSafresh1 } 183*3d61058aSafresh1 }; 184*3d61058aSafresh1} 185*3d61058aSafresh1 186*3d61058aSafresh1# Special testing of setting both accuracy and precision simultaneouly with 187*3d61058aSafresh1# config(). This didn't work correctly before. 188*3d61058aSafresh1 189*3d61058aSafresh1for my $class (@classes) { 190*3d61058aSafresh1 191*3d61058aSafresh1 note <<"EOF"; 192*3d61058aSafresh1 193*3d61058aSafresh1Verify that $class->config({accuracy => \$a, precision => \$p}) 194*3d61058aSafresh1works as intended. 195*3d61058aSafresh1 196*3d61058aSafresh1EOF 197*3d61058aSafresh1 198*3d61058aSafresh1 $class -> config({"accuracy" => 4, "precision" => undef}); 199*3d61058aSafresh1 200*3d61058aSafresh1 subtest qq|$class -> config({"accuracy" => 4, "precision" => undef})| 201*3d61058aSafresh1 => sub { 202*3d61058aSafresh1 plan tests => 2; 203*3d61058aSafresh1 204*3d61058aSafresh1 is($class -> config("accuracy"), 4, 205*3d61058aSafresh1 qq|$class -> config("accuracy")|); 206*3d61058aSafresh1 is($class -> config("precision"), undef, 207*3d61058aSafresh1 qq|$class -> config("precision")|); 208*3d61058aSafresh1 }; 209*3d61058aSafresh1 210*3d61058aSafresh1 $class -> config({"accuracy" => undef, "precision" => 5}); 211*3d61058aSafresh1 212*3d61058aSafresh1 subtest qq|$class -> config({"accuracy" => undef, "precision" => 5})| 213*3d61058aSafresh1 => sub { 214*3d61058aSafresh1 plan tests => 2; 215*3d61058aSafresh1 216*3d61058aSafresh1 is($class -> config("accuracy"), undef, 217*3d61058aSafresh1 qq|$class -> config("accuracy")|); 218*3d61058aSafresh1 is($class -> config("precision"), 5, 219*3d61058aSafresh1 qq|$class -> config("precision")|); 220*3d61058aSafresh1 }; 221*3d61058aSafresh1} 222*3d61058aSafresh1 223*3d61058aSafresh1# Test getting an invalid key (should croak) 224*3d61058aSafresh1 225*3d61058aSafresh1note <<"EOF"; 226*3d61058aSafresh1 227*3d61058aSafresh1Verify behaviour when getting an invalid key. 228*3d61058aSafresh1 229*3d61058aSafresh1EOF 230*3d61058aSafresh1 231*3d61058aSafresh1for my $class (@classes) { 232*3d61058aSafresh1 eval { $class->config('some_garbage' => 1); }; 233b8851fccSafresh1 like($@, 234b8851fccSafresh1 qr/ ^ Illegal \s+ key\(s\) \s+ 'some_garbage' \s+ passed \s+ to \s+ 235*3d61058aSafresh1 $class->config\(\) \s+ at 236b8851fccSafresh1 /x, 237*3d61058aSafresh1 "Passing invalid key to $class->config() causes an error."); 238*3d61058aSafresh1} 239