1N/A#!./perl -w
1N/A#
1N/A# Copyright 2002, Larry Wall.
1N/A#
1N/A# You may redistribute only under the same terms as Perl 5, as specified
1N/A# in the README file that comes with the distribution.
1N/A#
1N/A
1N/Asub BEGIN {
1N/A chdir('t') if -d 't';
1N/A if ($ENV{PERL_CORE}){
1N/A @INC = ('.', '../lib', '../ext/Storable/t');
1N/A require Config;
1N/A if ($Config::Config{'extensions'} !~ /\bStorable\b/) {
1N/A print "1..0 # Skip: Storable was not built\n";
1N/A exit 0;
1N/A }
1N/A } else {
1N/A if ($] < 5.005) {
1N/A print "1..0 # Skip: No Hash::Util pre 5.005\n";
1N/A exit 0;
1N/A # And doing this seems on 5.004 seems to create bogus warnings about
1N/A # unitialized variables, or coredumps in Perl_pp_padsv
1N/A } elsif (!eval "require Hash::Util") {
1N/A if ($@ =~ /Can\'t locate Hash\/Util\.pm in \@INC/s) {
1N/A print "1..0 # Skip: No Hash::Util:\n";
1N/A exit 0;
1N/A } else {
1N/A die;
1N/A }
1N/A }
1N/A unshift @INC, 't';
1N/A }
1N/A require 'st-dump.pl';
1N/A}
1N/A
1N/A
1N/Ause Storable qw(dclone freeze thaw);
1N/Ause Hash::Util qw(lock_hash unlock_value);
1N/A
1N/Aprint "1..100\n";
1N/A
1N/Amy %hash = (question => '?', answer => 42, extra => 'junk', undef => undef);
1N/Alock_hash %hash;
1N/Aunlock_value %hash, 'answer';
1N/Aunlock_value %hash, 'extra';
1N/Adelete $hash{'extra'};
1N/A
1N/Amy $test;
1N/A
1N/Apackage Restrict_Test;
1N/A
1N/Asub me_second {
1N/A return (undef, $_[0]);
1N/A}
1N/A
1N/Apackage main;
1N/A
1N/Asub freeze_thaw {
1N/A my $temp = freeze $_[0];
1N/A return thaw $temp;
1N/A}
1N/A
1N/Asub testit {
1N/A my $hash = shift;
1N/A my $cloner = shift;
1N/A my $copy = &$cloner($hash);
1N/A
1N/A my @in_keys = sort keys %$hash;
1N/A my @out_keys = sort keys %$copy;
1N/A unless (ok ++$test, "@in_keys" eq "@out_keys") {
1N/A print "# Failed: keys mis-match after deep clone.\n";
1N/A print "# Original keys: @in_keys\n";
1N/A print "# Copy's keys: @out_keys\n";
1N/A }
1N/A
1N/A # $copy = $hash; # used in initial debug of the tests
1N/A
1N/A ok ++$test, Internals::SvREADONLY(%$copy), "cloned hash restricted?";
1N/A
1N/A ok ++$test, Internals::SvREADONLY($copy->{question}),
1N/A "key 'question' not locked in copy?";
1N/A
1N/A ok ++$test, !Internals::SvREADONLY($copy->{answer}),
1N/A "key 'answer' not locked in copy?";
1N/A
1N/A eval { $copy->{extra} = 15 } ;
1N/A unless (ok ++$test, !$@, "Can assign to reserved key 'extra'?") {
1N/A my $diag = $@;
1N/A $diag =~ s/\n.*\z//s;
1N/A print "# \$\@: $diag\n";
1N/A }
1N/A
1N/A eval { $copy->{nono} = 7 } ;
1N/A ok ++$test, $@, "Can not assign to invalid key 'nono'?";
1N/A
1N/A ok ++$test, exists $copy->{undef},
1N/A "key 'undef' exists";
1N/A
1N/A ok ++$test, !defined $copy->{undef},
1N/A "value for key 'undef' is undefined";
1N/A}
1N/A
1N/Afor $Storable::canonical (0, 1) {
1N/A for my $cloner (\&dclone, \&freeze_thaw) {
1N/A print "# \$Storable::canonical = $Storable::canonical\n";
1N/A testit (\%hash, $cloner);
1N/A my $object = \%hash;
1N/A # bless {}, "Restrict_Test";
1N/A
1N/A my %hash2;
1N/A $hash2{"k$_"} = "v$_" for 0..16;
1N/A lock_hash %hash2;
1N/A for (0..16) {
1N/A unlock_value %hash2, "k$_";
1N/A delete $hash2{"k$_"};
1N/A }
1N/A my $copy = &$cloner(\%hash2);
1N/A
1N/A for (0..16) {
1N/A my $k = "k$_";
1N/A eval { $copy->{$k} = undef } ;
1N/A unless (ok ++$test, !$@, "Can assign to reserved key '$k'?") {
1N/A my $diag = $@;
1N/A $diag =~ s/\n.*\z//s;
1N/A print "# \$\@: $diag\n";
1N/A }
1N/A }
1N/A }
1N/A}