xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/ext/XS/APItest/t/hash.t (revision 0:68f95e015346)
1#!perl -w
2
3BEGIN {
4  chdir 't' if -d 't';
5  @INC = '../lib';
6  push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
7  require Config; import Config;
8  if ($Config{'extensions'} !~ /\bXS\/APItest\b/) {
9    # Look, I'm using this fully-qualified variable more than once!
10    my $arch = $MacPerl::Architecture;
11    print "1..0 # Skip: XS::APItest was not built\n";
12    exit 0;
13  }
14}
15
16use strict;
17use utf8;
18use Tie::Hash;
19use Test::More 'no_plan';
20
21use_ok('XS::APItest');
22
23sub preform_test;
24sub test_present;
25sub test_absent;
26sub test_delete_present;
27sub test_delete_absent;
28sub brute_force_exists;
29sub test_store;
30sub test_fetch_present;
31sub test_fetch_absent;
32
33my $utf8_for_258 = chr 258;
34utf8::encode $utf8_for_258;
35
36my @testkeys = ('N', chr 198, chr 256);
37my @keys = (@testkeys, $utf8_for_258);
38
39foreach (@keys) {
40  utf8::downgrade $_, 1;
41}
42main_tests (\@keys, \@testkeys, '');
43
44foreach (@keys) {
45  utf8::upgrade $_;
46}
47main_tests (\@keys, \@testkeys, ' [utf8 hash]');
48
49{
50  my %h = (a=>'cheat');
51  tie %h, 'Tie::StdHash';
52  is (XS::APItest::Hash::store(\%h, chr 258,  1), 1);
53
54  ok (!exists $h{$utf8_for_258},
55      "hv_store doesn't insert a key with the raw utf8 on a tied hash");
56}
57
58exit;
59
60################################   The End   ################################
61
62sub main_tests {
63  my ($keys, $testkeys, $description) = @_;
64  foreach my $key (@$testkeys) {
65    my $lckey = ($key eq chr 198) ? chr 230 : lc $key;
66    my $unikey = $key;
67    utf8::encode $unikey;
68
69    utf8::downgrade $key, 1;
70    utf8::downgrade $lckey, 1;
71    utf8::downgrade $unikey, 1;
72    main_test_inner ($key, $lckey, $unikey, $keys, $description);
73
74    utf8::upgrade $key;
75    utf8::upgrade $lckey;
76    utf8::upgrade $unikey;
77    main_test_inner ($key, $lckey, $unikey, $keys,
78		     $description . ' [key utf8 on]');
79  }
80
81  # hv_exists was buggy for tied hashes, in that the raw utf8 key was being
82  # used - the utf8 flag was being lost.
83  perform_test (\&test_absent, (chr 258), $keys, '');
84
85  perform_test (\&test_fetch_absent, (chr 258), $keys, '');
86  perform_test (\&test_delete_absent, (chr 258), $keys, '');
87}
88
89sub main_test_inner {
90  my ($key, $lckey, $unikey, $keys, $description) = @_;
91  perform_test (\&test_present, $key, $keys, $description);
92  perform_test (\&test_fetch_present, $key, $keys, $description);
93  perform_test (\&test_delete_present, $key, $keys, $description);
94
95  perform_test (\&test_store, $key, $keys, $description, [a=>'cheat']);
96  perform_test (\&test_store, $key, $keys, $description, []);
97
98  perform_test (\&test_absent, $lckey, $keys, $description);
99  perform_test (\&test_fetch_absent, $lckey, $keys, $description);
100  perform_test (\&test_delete_absent, $lckey, $keys, $description);
101
102  return if $unikey eq $key;
103
104  perform_test (\&test_absent, $unikey, $keys, $description);
105  perform_test (\&test_fetch_absent, $unikey, $keys, $description);
106  perform_test (\&test_delete_absent, $unikey, $keys, $description);
107}
108
109sub perform_test {
110  my ($test_sub, $key, $keys, $message, @other) = @_;
111  my $printable = join ',', map {ord} split //, $key;
112
113  my (%hash, %tiehash);
114  tie %tiehash, 'Tie::StdHash';
115
116  @hash{@$keys} = @$keys;
117  @tiehash{@$keys} = @$keys;
118
119  &$test_sub (\%hash, $key, $printable, $message, @other);
120  &$test_sub (\%tiehash, $key, $printable, "$message tie", @other);
121}
122
123sub test_present {
124  my ($hash, $key, $printable, $message) = @_;
125
126  ok (exists $hash->{$key}, "hv_exists_ent present$message $printable");
127  ok (XS::APItest::Hash::exists ($hash, $key),
128      "hv_exists present$message $printable");
129}
130
131sub test_absent {
132  my ($hash, $key, $printable, $message) = @_;
133
134  ok (!exists $hash->{$key}, "hv_exists_ent absent$message $printable");
135  ok (!XS::APItest::Hash::exists ($hash, $key),
136      "hv_exists absent$message $printable");
137}
138
139sub test_delete_present {
140  my ($hash, $key, $printable, $message) = @_;
141
142  my $copy = {};
143  my $class = tied %$hash;
144  if (defined $class) {
145    tie %$copy, ref $class;
146  }
147  $copy = {%$hash};
148  ok (brute_force_exists ($copy, $key),
149      "hv_delete_ent present$message $printable");
150  is (delete $copy->{$key}, $key, "hv_delete_ent present$message $printable");
151  ok (!brute_force_exists ($copy, $key),
152      "hv_delete_ent present$message $printable");
153  $copy = {%$hash};
154  ok (brute_force_exists ($copy, $key),
155      "hv_delete present$message $printable");
156  is (XS::APItest::Hash::delete ($copy, $key), $key,
157      "hv_delete present$message $printable");
158  ok (!brute_force_exists ($copy, $key),
159      "hv_delete present$message $printable");
160}
161
162sub test_delete_absent {
163  my ($hash, $key, $printable, $message) = @_;
164
165  my $copy = {};
166  my $class = tied %$hash;
167  if (defined $class) {
168    tie %$copy, ref $class;
169  }
170  $copy = {%$hash};
171  is (delete $copy->{$key}, undef, "hv_delete_ent absent$message $printable");
172  $copy = {%$hash};
173  is (XS::APItest::Hash::delete ($copy, $key), undef,
174      "hv_delete absent$message $printable");
175}
176
177sub test_store {
178  my ($hash, $key, $printable, $message, $defaults) = @_;
179  my $HV_STORE_IS_CRAZY = 1;
180
181  # We are cheating - hv_store returns NULL for a store into an empty
182  # tied hash. This isn't helpful here.
183
184  my $class = tied %$hash;
185
186  my %h1 = @$defaults;
187  my %h2 = @$defaults;
188  if (defined $class) {
189    tie %h1, ref $class;
190    tie %h2, ref $class;
191    $HV_STORE_IS_CRAZY = undef unless @$defaults;
192  }
193  is (XS::APItest::Hash::store_ent(\%h1, $key, 1), 1,
194      "hv_store_ent$message $printable");
195  ok (brute_force_exists (\%h1, $key), "hv_store_ent$message $printable");
196  is (XS::APItest::Hash::store(\%h2, $key,  1), $HV_STORE_IS_CRAZY,
197      "hv_store$message $printable");
198  ok (brute_force_exists (\%h2, $key), "hv_store$message $printable");
199}
200
201sub test_fetch_present {
202  my ($hash, $key, $printable, $message) = @_;
203
204  is ($hash->{$key}, $key, "hv_fetch_ent present$message $printable");
205  is (XS::APItest::Hash::fetch ($hash, $key), $key,
206      "hv_fetch present$message $printable");
207}
208
209sub test_fetch_absent {
210  my ($hash, $key, $printable, $message) = @_;
211
212  is ($hash->{$key}, undef, "hv_fetch_ent absent$message $printable");
213  is (XS::APItest::Hash::fetch ($hash, $key), undef,
214      "hv_fetch absent$message $printable");
215}
216
217sub brute_force_exists {
218  my ($hash, $key) = @_;
219  foreach (keys %$hash) {
220    return 1 if $key eq $_;
221  }
222  return 0;
223}
224