5 print "1..0 # Skip: no utf8 hash key support\n";
10 @INC = ('.', '../lib');
11 push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
15 require Config; import Config;
17 if($Config{'extensions'} !~ /\bStorable\b/) {
18 print "1..0 # Skip: Storable was not built\n";
25 our $DEBUGME = shift || 0;
26 use Storable qw(store nstore retrieve thaw freeze);
29 $Storable::DEBUGME = ($DEBUGME > 1);
31 # Better than no plan, because I was getting out of memory errors, at which
32 # point Test::More tidily prints up 1..79 as if I meant to finish there.
33 use Test::More tests=>148;
35 use Encode qw(is_utf8);
38 $Storable::canonical = $Storable::canonical; # Shut up a used only once warning.
40 for $Storable::canonical (0, 1) {
42 # first we generate a nasty hash which keys include both utf8
43 # on and off with identical PVs
45 no utf8; # we have a naked 8-bit byte below (in Latin 1, anyway)
47 # In Latin 1 -ese the below ord() should end up 0xc0 (192),
48 # in EBCDIC 0x64 (100). Both should end up being UTF-8/UTF-EBCDIC.
50 ord("Á"), # LATIN CAPITAL LETTER A WITH GRAVE
51 0x3000, #IDEOGRAPHIC SPACE
54 foreach my $i (@ords){
55 my $u = chr($i); utf8::upgrade($u);
56 # warn sprintf "%d,%d", bytes::length($u), is_utf8($u);
57 my $b = pack("C*", unpack("C*", $u));
58 # warn sprintf "%d,%d" ,bytes::length($b), is_utf8($b);
61 "equivalence - with utf8flag");
62 is (pack("C*", unpack("C*", $u)), pack("C*", unpack("C*", $b)),
63 "equivalence - without utf8flag");
65 $utf8hash{$u} = $utf8hash{$b} = $i;
70 return scalar keys %$href;
74 is($nk = nkeys(\%utf8hash), scalar(@ords)*2,
75 "nasty hash generated (nkeys=$nk)");
77 # now let the show begin!
79 my $thawed = thaw(freeze(\%utf8hash));
81 is($nk = nkeys($thawed),
83 "scalar keys \%{\$thawed} (nkeys=$nk)");
84 for my $k (sort keys %$thawed){
85 is($utf8hash{$k}, $thawed->{$k}, "frozen item chr($utf8hash{$k})");
88 my $storage = "utfhash.po"; # po = perl object!
91 ok((nstore \%utf8hash, $storage), "nstore to $storage");
92 ok(($retrieved = retrieve($storage)), "retrieve from $storage");
94 is($nk = nkeys($retrieved),
96 "scalar keys \%{\$retrieved} (nkeys=$nk)");
97 for my $k (sort keys %$retrieved){
98 is($utf8hash{$k}, $retrieved->{$k}, "nstored item chr($utf8hash{$k})");
103 ok((store \%utf8hash, $storage), "store to $storage");
104 ok(($retrieved = retrieve($storage)), "retrieve from $storage");
105 is($nk = nkeys($retrieved),
107 "scalar keys \%{\$retrieved} (nkeys=$nk)");
108 for my $k (sort keys %$retrieved){
109 is($utf8hash{$k}, $retrieved->{$k}, "stored item chr($utf8hash{$k})");
111 $DEBUGME or unlink $storage;
113 # On the premis that more tests are good, here are NWC's tests:
118 return (undef, $_[0]);
123 my $utf8 = "Schlo\xdf" . chr 256;
126 # Set this to 1 to test the test by bypassing Storable.
130 my ($object, $package) = @_;
132 is ref $object, 'HASH', "$object is unblessed";
135 isa_ok ($object, $package);
136 my ($garbage, $copy) = eval {$object->me_second};
137 is $@, "", "check it has correct method";
138 cmp_ok $copy, '==', $object, "and that it returns the same object";
141 # Thanks to Dan Kogai for the Kanji for "castle" (which he informs me also
142 # means 'a city' in Mandarin).
143 my %hash = (map {$_, $_} 'castle', "ch\xe5teau", $utf8, "\x{57CE}");
145 for my $package ('', 'Hash_Test') {
146 # Run through and sanity check these.
148 bless \%hash, $package;
152 my $r = 0 + $hash{$_} =~ /^\w+$/;
153 cmp_ok ($l, '==', $r);
156 # Grr. This cperl mode thinks that ${ is a punctuation variable.
157 # I presume it's punishment for using xemacs rather than emacs. Or OS/2 :-)
158 my $copy = $bypass ? \%hash : ${thaw freeze \\%hash};
159 class_test ($copy, $package);
163 my $r = 0 + $copy->{$_} =~ /^\w+$/;
164 cmp_ok ($l, '==', $r, sprintf "key length %d", length $_);
168 my $bytes = my $char = chr 27182;
169 utf8::encode ($bytes);
171 my $orig = {$char => 1};
173 bless $orig, $package;
175 my $just_utf8 = $bypass ? $orig : ${thaw freeze \$orig};
176 class_test ($just_utf8, $package);
177 cmp_ok (scalar keys %$just_utf8, '==', 1, "1 key in utf8?");
178 cmp_ok ($just_utf8->{$char}, '==', 1, "utf8 key present?");
179 ok (!exists $just_utf8->{$bytes}, "bytes key absent?");
181 $orig = {$bytes => 1};
183 bless $orig, $package;
185 my $just_bytes = $bypass ? $orig : ${thaw freeze \$orig};
186 class_test ($just_bytes, $package);
188 cmp_ok (scalar keys %$just_bytes, '==', 1, "1 key in bytes?");
189 cmp_ok ($just_bytes->{$bytes}, '==', 1, "bytes key present?");
190 ok (!exists $just_bytes->{$char}, "utf8 key absent?");
192 die sprintf "Both have length %d, which is crazy", length $char
193 if length $char == length $bytes;
195 $orig = {$bytes => length $bytes, $char => length $char};
197 bless $orig, $package;
199 my $both = $bypass ? $orig : ${thaw freeze \$orig};
200 class_test ($both, $package);
202 cmp_ok (scalar keys %$both, '==', 2, "2 keys?");
203 cmp_ok ($both->{$bytes}, '==', length $bytes, "bytes key present?");
204 cmp_ok ($both->{$char}, '==', length $char, "utf8 key present?");