summaryrefslogtreecommitdiff
path: root/ext/Storable/t/canonical.t
diff options
context:
space:
mode:
Diffstat (limited to 'ext/Storable/t/canonical.t')
-rw-r--r--ext/Storable/t/canonical.t153
1 files changed, 153 insertions, 0 deletions
diff --git a/ext/Storable/t/canonical.t b/ext/Storable/t/canonical.t
new file mode 100644
index 0000000000..b55669b653
--- /dev/null
+++ b/ext/Storable/t/canonical.t
@@ -0,0 +1,153 @@
+#!./perl
+
+# $Id: canonical.t,v 1.0 2000/09/01 19:40:41 ram Exp $
+#
+# Copyright (c) 1995-2000, Raphael Manfredi
+#
+# You may redistribute only under the same terms as Perl 5, as specified
+# in the README file that comes with the distribution.
+#
+# $Log: canonical.t,v $
+# Revision 1.0 2000/09/01 19:40:41 ram
+# Baseline for first official release.
+#
+
+sub BEGIN {
+ chdir('t') if -d 't';
+ @INC = '.';
+ push @INC, '../lib';
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bStorable\b/) {
+ print "1..0 # Skip: Storable was not built\n";
+ exit 0;
+ }
+}
+
+
+use Storable qw(freeze thaw dclone);
+use vars qw($debugging $verbose);
+
+print "1..8\n";
+
+sub ok {
+ my($testno, $ok) = @_;
+ print "not " unless $ok;
+ print "ok $testno\n";
+}
+
+
+# Uncomment the folowing line to get a dump of the constructed data structure
+# (you may want to reduce the size of the hashes too)
+# $debugging = 1;
+
+$hashsize = 100;
+$maxhash2size = 100;
+$maxarraysize = 100;
+
+# Use MD5 if its available to make random string keys
+
+eval { require "MD5.pm" };
+$gotmd5 = !$@;
+
+# Use Data::Dumper if debugging and it is available to create an ASCII dump
+
+if ($debugging) {
+ eval { require "Data/Dumper.pm" };
+ $gotdd = !$@;
+}
+
+@fixed_strings = ("January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December" );
+
+# Build some arbitrarily complex data structure starting with a top level hash
+# (deeper levels contain scalars, references to hashes or references to arrays);
+
+for (my $i = 0; $i < $hashsize; $i++) {
+ my($k) = int(rand(1_000_000));
+ $k = MD5->hexhash($k) if $gotmd5 and int(rand(2));
+ $a1{$k} = { key => "$k", value => $i };
+
+ # A third of the elements are references to further hashes
+
+ if (int(rand(1.5))) {
+ my($hash2) = {};
+ my($hash2size) = int(rand($maxhash2size));
+ while ($hash2size--) {
+ my($k2) = $k . $i . int(rand(100));
+ $hash2->{$k2} = $fixed_strings[rand(int(@fixed_strings))];
+ }
+ $a1{$k}->{value} = $hash2;
+ }
+
+ # A further third are references to arrays
+
+ elsif (int(rand(2))) {
+ my($arr_ref) = [];
+ my($arraysize) = int(rand($maxarraysize));
+ while ($arraysize--) {
+ push(@$arr_ref, $fixed_strings[rand(int(@fixed_strings))]);
+ }
+ $a1{$k}->{value} = $arr_ref;
+ }
+}
+
+
+print STDERR Data::Dumper::Dumper(\%a1) if ($verbose and $gotdd);
+
+
+# Copy the hash, element by element in order of the keys
+
+foreach $k (sort keys %a1) {
+ $a2{$k} = { key => "$k", value => $a1{$k}->{value} };
+}
+
+# Deep clone the hash
+
+$a3 = dclone(\%a1);
+
+# In canonical mode the frozen representation of each of the hashes
+# should be identical
+
+$Storable::canonical = 1;
+
+$x1 = freeze(\%a1);
+$x2 = freeze(\%a2);
+$x3 = freeze($a3);
+
+ok 1, (length($x1) > $hashsize); # sanity check
+ok 2, length($x1) == length($x2); # idem
+ok 3, $x1 eq $x2;
+ok 4, $x1 eq $x3;
+
+# In normal mode it is exceedingly unlikely that the frozen
+# representaions of all the hashes will be the same (normally the hash
+# elements are frozen in the order they are stored internally,
+# i.e. pseudo-randomly).
+
+$Storable::canonical = 0;
+
+$x1 = freeze(\%a1);
+$x2 = freeze(\%a2);
+$x3 = freeze($a3);
+
+
+# Two out of three the same may be a coincidence, all three the same
+# is much, much more unlikely. Still it could happen, so this test
+# may report a false negative.
+
+ok 5, ($x1 ne $x2) || ($x1 ne $x3);
+
+
+# Ensure refs to "undef" values are properly shared
+# Same test as in t/dclone.t to ensure the "canonical" code is also correct
+
+my $hash;
+push @{$$hash{''}}, \$$hash{a};
+ok 6, $$hash{''}[0] == \$$hash{a};
+
+my $cloned = dclone(dclone($hash));
+ok 7, $$cloned{''}[0] == \$$cloned{a};
+
+$$cloned{a} = "blah";
+ok 8, $$cloned{''}[0] == \$$cloned{a};
+