for Configure -Dnoextensions=Encode
[p5sagit/p5-mst-13.2.git] / ext / Storable / t / utf8hash.t
1 #!./perl
2
3 sub BEGIN {
4     if ($] < 5.007) {
5         print "1..0 # Skip: no utf8 hash key support\n";
6         exit 0;
7     }
8     if ($ENV{PERL_CORE}){
9         chdir('t') if -d 't';
10         @INC = ('.', '../lib');
11         push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
12     } else {
13         unshift @INC, 't';
14     }
15     require Config; import Config;
16     if ($ENV{PERL_CORE}){
17         if($Config{'extensions'} !~ /\bStorable\b/) {
18             print "1..0 # Skip: Storable was not built\n";
19             exit 0;
20         }
21     }
22 }
23
24 use strict;
25 our $DEBUGME = shift || 0;
26 use Storable qw(store nstore retrieve thaw freeze);
27 {
28     no warnings;
29     $Storable::DEBUGME = ($DEBUGME > 1);
30 }
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;
34 use bytes ();
35 my %utf8hash;
36
37 $Storable::canonical = $Storable::canonical; # Shut up a used only once warning.
38
39 for $Storable::canonical (0, 1) {
40
41 # first we generate a nasty hash which keys include both utf8
42 # on and off with identical PVs
43
44 no utf8; # we have a naked 8-bit byte below (in Latin 1, anyway)
45
46 # In Latin 1 -ese the below ord() should end up 0xc0 (192),
47 # in EBCDIC 0x64 (100).  Both should end up being UTF-8/UTF-EBCDIC.
48 my @ords = (
49             ord("Á"), # LATIN CAPITAL LETTER A WITH GRAVE
50             0x3000, #IDEOGRAPHIC SPACE
51            );
52
53 foreach my $i (@ords){
54     my $u = chr($i); utf8::upgrade($u);
55     # warn sprintf "%d,%d", bytes::length($u), is_utf8($u);
56     my $b = pack("C*", unpack("C*", $u));
57     # warn sprintf "%d,%d" ,bytes::length($b), is_utf8($b);
58
59     isnt($u,                            $b, 
60          "equivalence - with utf8flag");
61     is   (pack("C*", unpack("C*", $u)), pack("C*", unpack("C*", $b)),
62           "equivalence - without utf8flag");
63
64     $utf8hash{$u} = $utf8hash{$b} = $i;
65 }
66
67 sub nkeys($){
68     my $href = shift;
69     return scalar keys %$href; 
70 }
71
72 my $nk;
73 is($nk = nkeys(\%utf8hash), scalar(@ords)*2, 
74    "nasty hash generated (nkeys=$nk)");
75
76 # now let the show begin!
77
78 my $thawed = thaw(freeze(\%utf8hash));
79
80 is($nk = nkeys($thawed),
81    nkeys(\%utf8hash),
82    "scalar keys \%{\$thawed} (nkeys=$nk)");
83 for my $k (sort keys %$thawed){
84     is($utf8hash{$k}, $thawed->{$k}, "frozen item chr($utf8hash{$k})");
85 }
86
87 my $storage = "utfhash.po"; # po = perl object!
88 my $retrieved;
89
90 ok((nstore \%utf8hash, $storage), "nstore to $storage");
91 ok(($retrieved = retrieve($storage)), "retrieve from $storage");
92
93 is($nk = nkeys($retrieved),
94    nkeys(\%utf8hash),
95    "scalar keys \%{\$retrieved} (nkeys=$nk)");
96 for my $k (sort keys %$retrieved){
97     is($utf8hash{$k}, $retrieved->{$k}, "nstored item chr($utf8hash{$k})");
98 }
99 unlink $storage;
100
101
102 ok((store \%utf8hash, $storage), "store to $storage");
103 ok(($retrieved = retrieve($storage)), "retrieve from $storage");
104 is($nk = nkeys($retrieved),
105    nkeys(\%utf8hash),
106    "scalar keys \%{\$retrieved} (nkeys=$nk)");
107 for my $k (sort keys %$retrieved){
108     is($utf8hash{$k}, $retrieved->{$k}, "stored item chr($utf8hash{$k})");
109 }
110 $DEBUGME or unlink $storage;
111
112 # On the premis that more tests are good, here are NWC's tests:
113
114 package Hash_Test;
115
116 sub me_second {
117   return (undef, $_[0]);
118 }
119
120 package main;
121
122 my $utf8 = "Schlo\xdf" . chr 256;
123 chop $utf8;
124
125 # Set this to 1 to test the test by bypassing Storable.
126 my $bypass = 0;
127
128 sub class_test {
129   my ($object, $package) = @_;
130   unless ($package) {
131     is ref $object, 'HASH', "$object is unblessed";
132     return;
133   }
134   isa_ok ($object, $package);
135   my ($garbage, $copy) = eval {$object->me_second};
136   is $@, "", "check it has correct method";
137   cmp_ok $copy, '==', $object, "and that it returns the same object";
138 }
139
140 # Thanks to Dan Kogai for the Kanji for "castle" (which he informs me also
141 # means 'a city' in Mandarin).
142 my %hash = (map {$_, $_} 'castle', "ch\xe5teau", $utf8, "\x{57CE}");
143
144 for my $package ('', 'Hash_Test') {
145   # Run through and sanity check these.
146   if ($package) {
147     bless \%hash, $package;
148   }
149   for (keys %hash) {
150     my $l = 0 + /^\w+$/;
151     my $r = 0 + $hash{$_} =~ /^\w+$/;
152     cmp_ok ($l, '==', $r);
153   }
154
155   # Grr. This cperl mode thinks that ${ is a punctuation variable.
156   # I presume it's punishment for using xemacs rather than emacs. Or OS/2 :-)
157   my $copy = $bypass ? \%hash : ${thaw freeze \\%hash};
158   class_test ($copy, $package);
159
160   for (keys %$copy) {
161     my $l = 0 + /^\w+$/;
162     my $r = 0 + $copy->{$_} =~ /^\w+$/;
163     cmp_ok ($l, '==', $r, sprintf "key length %d", length $_);
164   }
165
166
167   my $bytes = my $char = chr 27182;
168   utf8::encode ($bytes);
169
170   my $orig = {$char => 1};
171   if ($package) {
172     bless $orig, $package;
173   }
174   my $just_utf8 = $bypass ? $orig : ${thaw freeze \$orig};
175   class_test ($just_utf8, $package);
176   cmp_ok (scalar keys %$just_utf8, '==', 1, "1 key in utf8?");
177   cmp_ok ($just_utf8->{$char}, '==', 1, "utf8 key present?");
178   ok (!exists $just_utf8->{$bytes}, "bytes key absent?");
179
180   $orig = {$bytes => 1};
181   if ($package) {
182     bless $orig, $package;
183   }
184   my $just_bytes = $bypass ? $orig : ${thaw freeze \$orig};
185   class_test ($just_bytes, $package);
186
187   cmp_ok (scalar keys %$just_bytes, '==', 1, "1 key in bytes?");
188   cmp_ok ($just_bytes->{$bytes}, '==', 1, "bytes key present?");
189   ok (!exists $just_bytes->{$char}, "utf8 key absent?");
190
191   die sprintf "Both have length %d, which is crazy", length $char
192     if length $char == length $bytes;
193
194   $orig = {$bytes => length $bytes, $char => length $char};
195   if ($package) {
196     bless $orig, $package;
197   }
198   my $both = $bypass ? $orig : ${thaw freeze \$orig};
199   class_test ($both, $package);
200
201   cmp_ok (scalar keys %$both, '==', 2, "2 keys?");
202   cmp_ok ($both->{$bytes}, '==', length $bytes, "bytes key present?");
203   cmp_ok ($both->{$char}, '==', length $char, "utf8 key present?");
204 }
205
206 }