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