1 | #!./perl
|
---|
2 |
|
---|
3 | # Add new tests to the end with format:
|
---|
4 | # ########
|
---|
5 | #
|
---|
6 | # # test description
|
---|
7 | # Test code
|
---|
8 | # EXPECT
|
---|
9 | # Warn or die msgs (if any) at - line 1234
|
---|
10 | #
|
---|
11 |
|
---|
12 | chdir 't' if -d 't';
|
---|
13 | @INC = '../lib';
|
---|
14 | $ENV{PERL5LIB} = "../lib";
|
---|
15 |
|
---|
16 | $|=1;
|
---|
17 |
|
---|
18 | undef $/;
|
---|
19 | @prgs = split /^########\n/m, <DATA>;
|
---|
20 |
|
---|
21 | require './test.pl';
|
---|
22 | plan(tests => scalar @prgs);
|
---|
23 | for (@prgs){
|
---|
24 | ++$i;
|
---|
25 | my($prog,$expected) = split(/\nEXPECT\n/, $_, 2);
|
---|
26 | print("not ok $i # bad test format\n"), next
|
---|
27 | unless defined $expected;
|
---|
28 | my ($testname) = $prog =~ /^# (.*)\n/m;
|
---|
29 | $testname ||= '';
|
---|
30 | $TODO = $testname =~ s/^TODO //;
|
---|
31 | $results =~ s/\n+$//;
|
---|
32 | $expected =~ s/\n+$//;
|
---|
33 |
|
---|
34 | fresh_perl_is($prog, $expected, {}, $testname);
|
---|
35 | }
|
---|
36 |
|
---|
37 | __END__
|
---|
38 |
|
---|
39 | # standard behaviour, without any extra references
|
---|
40 | use Tie::Hash ;
|
---|
41 | tie %h, Tie::StdHash;
|
---|
42 | untie %h;
|
---|
43 | EXPECT
|
---|
44 | ########
|
---|
45 |
|
---|
46 | # standard behaviour, without any extra references
|
---|
47 | use Tie::Hash ;
|
---|
48 | {package Tie::HashUntie;
|
---|
49 | use base 'Tie::StdHash';
|
---|
50 | sub UNTIE
|
---|
51 | {
|
---|
52 | warn "Untied\n";
|
---|
53 | }
|
---|
54 | }
|
---|
55 | tie %h, Tie::HashUntie;
|
---|
56 | untie %h;
|
---|
57 | EXPECT
|
---|
58 | Untied
|
---|
59 | ########
|
---|
60 |
|
---|
61 | # standard behaviour, with 1 extra reference
|
---|
62 | use Tie::Hash ;
|
---|
63 | $a = tie %h, Tie::StdHash;
|
---|
64 | untie %h;
|
---|
65 | EXPECT
|
---|
66 | ########
|
---|
67 |
|
---|
68 | # standard behaviour, with 1 extra reference via tied
|
---|
69 | use Tie::Hash ;
|
---|
70 | tie %h, Tie::StdHash;
|
---|
71 | $a = tied %h;
|
---|
72 | untie %h;
|
---|
73 | EXPECT
|
---|
74 | ########
|
---|
75 |
|
---|
76 | # standard behaviour, with 1 extra reference which is destroyed
|
---|
77 | use Tie::Hash ;
|
---|
78 | $a = tie %h, Tie::StdHash;
|
---|
79 | $a = 0 ;
|
---|
80 | untie %h;
|
---|
81 | EXPECT
|
---|
82 | ########
|
---|
83 |
|
---|
84 | # standard behaviour, with 1 extra reference via tied which is destroyed
|
---|
85 | use Tie::Hash ;
|
---|
86 | tie %h, Tie::StdHash;
|
---|
87 | $a = tied %h;
|
---|
88 | $a = 0 ;
|
---|
89 | untie %h;
|
---|
90 | EXPECT
|
---|
91 | ########
|
---|
92 |
|
---|
93 | # strict behaviour, without any extra references
|
---|
94 | use warnings 'untie';
|
---|
95 | use Tie::Hash ;
|
---|
96 | tie %h, Tie::StdHash;
|
---|
97 | untie %h;
|
---|
98 | EXPECT
|
---|
99 | ########
|
---|
100 |
|
---|
101 | # strict behaviour, with 1 extra references generating an error
|
---|
102 | use warnings 'untie';
|
---|
103 | use Tie::Hash ;
|
---|
104 | $a = tie %h, Tie::StdHash;
|
---|
105 | untie %h;
|
---|
106 | EXPECT
|
---|
107 | untie attempted while 1 inner references still exist at - line 6.
|
---|
108 | ########
|
---|
109 |
|
---|
110 | # strict behaviour, with 1 extra references via tied generating an error
|
---|
111 | use warnings 'untie';
|
---|
112 | use Tie::Hash ;
|
---|
113 | tie %h, Tie::StdHash;
|
---|
114 | $a = tied %h;
|
---|
115 | untie %h;
|
---|
116 | EXPECT
|
---|
117 | untie attempted while 1 inner references still exist at - line 7.
|
---|
118 | ########
|
---|
119 |
|
---|
120 | # strict behaviour, with 1 extra references which are destroyed
|
---|
121 | use warnings 'untie';
|
---|
122 | use Tie::Hash ;
|
---|
123 | $a = tie %h, Tie::StdHash;
|
---|
124 | $a = 0 ;
|
---|
125 | untie %h;
|
---|
126 | EXPECT
|
---|
127 | ########
|
---|
128 |
|
---|
129 | # strict behaviour, with extra 1 references via tied which are destroyed
|
---|
130 | use warnings 'untie';
|
---|
131 | use Tie::Hash ;
|
---|
132 | tie %h, Tie::StdHash;
|
---|
133 | $a = tied %h;
|
---|
134 | $a = 0 ;
|
---|
135 | untie %h;
|
---|
136 | EXPECT
|
---|
137 | ########
|
---|
138 |
|
---|
139 | # strict error behaviour, with 2 extra references
|
---|
140 | use warnings 'untie';
|
---|
141 | use Tie::Hash ;
|
---|
142 | $a = tie %h, Tie::StdHash;
|
---|
143 | $b = tied %h ;
|
---|
144 | untie %h;
|
---|
145 | EXPECT
|
---|
146 | untie attempted while 2 inner references still exist at - line 7.
|
---|
147 | ########
|
---|
148 |
|
---|
149 | # strict behaviour, check scope of strictness.
|
---|
150 | no warnings 'untie';
|
---|
151 | use Tie::Hash ;
|
---|
152 | $A = tie %H, Tie::StdHash;
|
---|
153 | $C = $B = tied %H ;
|
---|
154 | {
|
---|
155 | use warnings 'untie';
|
---|
156 | use Tie::Hash ;
|
---|
157 | tie %h, Tie::StdHash;
|
---|
158 | untie %h;
|
---|
159 | }
|
---|
160 | untie %H;
|
---|
161 | EXPECT
|
---|
162 | ########
|
---|
163 |
|
---|
164 | # Forbidden aggregate self-ties
|
---|
165 | sub Self::TIEHASH { bless $_[1], $_[0] }
|
---|
166 | {
|
---|
167 | my %c;
|
---|
168 | tie %c, 'Self', \%c;
|
---|
169 | }
|
---|
170 | EXPECT
|
---|
171 | Self-ties of arrays and hashes are not supported at - line 6.
|
---|
172 | ########
|
---|
173 |
|
---|
174 | # Allowed scalar self-ties
|
---|
175 | my $destroyed = 0;
|
---|
176 | sub Self::TIESCALAR { bless $_[1], $_[0] }
|
---|
177 | sub Self::DESTROY { $destroyed = 1; }
|
---|
178 | {
|
---|
179 | my $c = 42;
|
---|
180 | tie $c, 'Self', \$c;
|
---|
181 | }
|
---|
182 | die "self-tied scalar not DESTROYed" unless $destroyed == 1;
|
---|
183 | EXPECT
|
---|
184 | ########
|
---|
185 |
|
---|
186 | # Allowed glob self-ties
|
---|
187 | my $destroyed = 0;
|
---|
188 | my $printed = 0;
|
---|
189 | sub Self2::TIEHANDLE { bless $_[1], $_[0] }
|
---|
190 | sub Self2::DESTROY { $destroyed = 1; }
|
---|
191 | sub Self2::PRINT { $printed = 1; }
|
---|
192 | {
|
---|
193 | use Symbol;
|
---|
194 | my $c = gensym;
|
---|
195 | tie *$c, 'Self2', $c;
|
---|
196 | print $c 'Hello';
|
---|
197 | }
|
---|
198 | die "self-tied glob not PRINTed" unless $printed == 1;
|
---|
199 | die "self-tied glob not DESTROYed" unless $destroyed == 1;
|
---|
200 | EXPECT
|
---|
201 | ########
|
---|
202 |
|
---|
203 | # Allowed IO self-ties
|
---|
204 | my $destroyed = 0;
|
---|
205 | sub Self3::TIEHANDLE { bless $_[1], $_[0] }
|
---|
206 | sub Self3::DESTROY { $destroyed = 1; }
|
---|
207 | sub Self3::PRINT { $printed = 1; }
|
---|
208 | {
|
---|
209 | use Symbol 'geniosym';
|
---|
210 | my $c = geniosym;
|
---|
211 | tie *$c, 'Self3', $c;
|
---|
212 | print $c 'Hello';
|
---|
213 | }
|
---|
214 | die "self-tied IO not PRINTed" unless $printed == 1;
|
---|
215 | die "self-tied IO not DESTROYed" unless $destroyed == 1;
|
---|
216 | EXPECT
|
---|
217 | ########
|
---|
218 |
|
---|
219 | # TODO IO "self-tie" via TEMP glob
|
---|
220 | my $destroyed = 0;
|
---|
221 | sub Self3::TIEHANDLE { bless $_[1], $_[0] }
|
---|
222 | sub Self3::DESTROY { $destroyed = 1; }
|
---|
223 | sub Self3::PRINT { $printed = 1; }
|
---|
224 | {
|
---|
225 | use Symbol 'geniosym';
|
---|
226 | my $c = geniosym;
|
---|
227 | tie *$c, 'Self3', \*$c;
|
---|
228 | print $c 'Hello';
|
---|
229 | }
|
---|
230 | die "IO tied to TEMP glob not PRINTed" unless $printed == 1;
|
---|
231 | die "IO tied to TEMP glob not DESTROYed" unless $destroyed == 1;
|
---|
232 | EXPECT
|
---|
233 | ########
|
---|
234 |
|
---|
235 | # Interaction of tie and vec
|
---|
236 |
|
---|
237 | my ($a, $b);
|
---|
238 | use Tie::Scalar;
|
---|
239 | tie $a,Tie::StdScalar or die;
|
---|
240 | vec($b,1,1)=1;
|
---|
241 | $a = $b;
|
---|
242 | vec($a,1,1)=0;
|
---|
243 | vec($b,1,1)=0;
|
---|
244 | die unless $a eq $b;
|
---|
245 | EXPECT
|
---|
246 | ########
|
---|
247 |
|
---|
248 | # correct unlocalisation of tied hashes (patch #16431)
|
---|
249 | use Tie::Hash ;
|
---|
250 | tie %tied, Tie::StdHash;
|
---|
251 | { local $hash{'foo'} } warn "plain hash bad unlocalize" if exists $hash{'foo'};
|
---|
252 | { local $tied{'foo'} } warn "tied hash bad unlocalize" if exists $tied{'foo'};
|
---|
253 | { local $ENV{'foo'} } warn "%ENV bad unlocalize" if exists $ENV{'foo'};
|
---|
254 | EXPECT
|
---|
255 | ########
|
---|
256 |
|
---|
257 | # An attempt at lvalueable barewords broke this
|
---|
258 | tie FH, 'main';
|
---|
259 | EXPECT
|
---|
260 | Can't modify constant item in tie at - line 3, near "'main';"
|
---|
261 | Execution of - aborted due to compilation errors.
|
---|
262 | ########
|
---|
263 |
|
---|
264 | # localizing tied hash slices
|
---|
265 | $ENV{FooA} = 1;
|
---|
266 | $ENV{FooB} = 2;
|
---|
267 | print exists $ENV{FooA} ? 1 : 0, "\n";
|
---|
268 | print exists $ENV{FooB} ? 2 : 0, "\n";
|
---|
269 | print exists $ENV{FooC} ? 3 : 0, "\n";
|
---|
270 | {
|
---|
271 | local @ENV{qw(FooA FooC)};
|
---|
272 | print exists $ENV{FooA} ? 4 : 0, "\n";
|
---|
273 | print exists $ENV{FooB} ? 5 : 0, "\n";
|
---|
274 | print exists $ENV{FooC} ? 6 : 0, "\n";
|
---|
275 | }
|
---|
276 | print exists $ENV{FooA} ? 7 : 0, "\n";
|
---|
277 | print exists $ENV{FooB} ? 8 : 0, "\n";
|
---|
278 | print exists $ENV{FooC} ? 9 : 0, "\n"; # this should not exist
|
---|
279 | EXPECT
|
---|
280 | 1
|
---|
281 | 2
|
---|
282 | 0
|
---|
283 | 4
|
---|
284 | 5
|
---|
285 | 6
|
---|
286 | 7
|
---|
287 | 8
|
---|
288 | 0
|
---|
289 | ########
|
---|
290 | #
|
---|
291 | # FETCH freeing tie'd SV
|
---|
292 | sub TIESCALAR { bless [] }
|
---|
293 | sub FETCH { *a = \1; 1 }
|
---|
294 | tie $a, 'main';
|
---|
295 | print $a;
|
---|
296 | EXPECT
|
---|
297 | ########
|
---|
298 |
|
---|
299 | # [20020716.007] - nested FETCHES
|
---|
300 |
|
---|
301 | sub F1::TIEARRAY { bless [], 'F1' }
|
---|
302 | sub F1::FETCH { 1 }
|
---|
303 | my @f1;
|
---|
304 | tie @f1, 'F1';
|
---|
305 |
|
---|
306 | sub F2::TIEARRAY { bless [2], 'F2' }
|
---|
307 | sub F2::FETCH { my $self = shift; my $x = $f1[3]; $self }
|
---|
308 | my @f2;
|
---|
309 | tie @f2, 'F2';
|
---|
310 |
|
---|
311 | print $f2[4][0],"\n";
|
---|
312 |
|
---|
313 | sub F3::TIEHASH { bless [], 'F3' }
|
---|
314 | sub F3::FETCH { 1 }
|
---|
315 | my %f3;
|
---|
316 | tie %f3, 'F3';
|
---|
317 |
|
---|
318 | sub F4::TIEHASH { bless [3], 'F4' }
|
---|
319 | sub F4::FETCH { my $self = shift; my $x = $f3{3}; $self }
|
---|
320 | my %f4;
|
---|
321 | tie %f4, 'F4';
|
---|
322 |
|
---|
323 | print $f4{'foo'}[0],"\n";
|
---|
324 |
|
---|
325 | EXPECT
|
---|
326 | 2
|
---|
327 | 3
|
---|
328 | ########
|
---|
329 | # test untie() from within FETCH
|
---|
330 | package Foo;
|
---|
331 | sub TIESCALAR { my $pkg = shift; return bless [@_], $pkg; }
|
---|
332 | sub FETCH {
|
---|
333 | my $self = shift;
|
---|
334 | my ($obj, $field) = @$self;
|
---|
335 | untie $obj->{$field};
|
---|
336 | $obj->{$field} = "Bar";
|
---|
337 | }
|
---|
338 | package main;
|
---|
339 | tie $a->{foo}, "Foo", $a, "foo";
|
---|
340 | $a->{foo}; # access once
|
---|
341 | # the hash element should not be tied anymore
|
---|
342 | print defined tied $a->{foo} ? "not ok" : "ok";
|
---|
343 | EXPECT
|
---|
344 | ok
|
---|
345 | ########
|
---|
346 | # the tmps returned by FETCH should appear to be SCALAR
|
---|
347 | # (even though they are now implemented using PVLVs.)
|
---|
348 | package X;
|
---|
349 | sub TIEHASH { bless {} }
|
---|
350 | sub TIEARRAY { bless {} }
|
---|
351 | sub FETCH {1}
|
---|
352 | my (%h, @a);
|
---|
353 | tie %h, 'X';
|
---|
354 | tie @a, 'X';
|
---|
355 | my $r1 = \$h{1};
|
---|
356 | my $r2 = \$a[0];
|
---|
357 | my $s = "$r1 ". ref($r1) . " $r2 " . ref($r2);
|
---|
358 | $s=~ s/\(0x\w+\)//g;
|
---|
359 | print $s, "\n";
|
---|
360 | EXPECT
|
---|
361 | SCALAR SCALAR SCALAR SCALAR
|
---|
362 | ########
|
---|
363 | # [perl #23287] segfault in untie
|
---|
364 | sub TIESCALAR { bless $_[1], $_[0] }
|
---|
365 | my $var;
|
---|
366 | tie $var, 'main', \$var;
|
---|
367 | untie $var;
|
---|
368 | EXPECT
|
---|
369 | ########
|
---|
370 | # Test case from perlmonks by runrig
|
---|
371 | # http://www.perlmonks.org/index.pl?node_id=273490
|
---|
372 | # "Here is what I tried. I think its similar to what you've tried
|
---|
373 | # above. Its odd but convienient that after untie'ing you are left with
|
---|
374 | # a variable that has the same value as was last returned from
|
---|
375 | # FETCH. (At least on my perl v5.6.1). So you don't need to pass a
|
---|
376 | # reference to the variable in order to set it after the untie (here it
|
---|
377 | # is accessed through a closure)."
|
---|
378 | use strict;
|
---|
379 | use warnings;
|
---|
380 | package MyTied;
|
---|
381 | sub TIESCALAR {
|
---|
382 | my ($class,$code) = @_;
|
---|
383 | bless $code, $class;
|
---|
384 | }
|
---|
385 | sub FETCH {
|
---|
386 | my $self = shift;
|
---|
387 | print "Untie\n";
|
---|
388 | $self->();
|
---|
389 | }
|
---|
390 | package main;
|
---|
391 | my $var;
|
---|
392 | tie $var, 'MyTied', sub { untie $var; 4 };
|
---|
393 | print "One\n";
|
---|
394 | print "$var\n";
|
---|
395 | print "Two\n";
|
---|
396 | print "$var\n";
|
---|
397 | print "Three\n";
|
---|
398 | print "$var\n";
|
---|
399 | EXPECT
|
---|
400 | One
|
---|
401 | Untie
|
---|
402 | 4
|
---|
403 | Two
|
---|
404 | 4
|
---|
405 | Three
|
---|
406 | 4
|
---|
407 | ########
|
---|
408 | # [perl #22297] cannot untie scalar from within tied FETCH
|
---|
409 | my $counter = 0;
|
---|
410 | my $x = 7;
|
---|
411 | my $ref = \$x;
|
---|
412 | tie $x, 'Overlay', $ref, $x;
|
---|
413 | my $y;
|
---|
414 | $y = $x;
|
---|
415 | $y = $x;
|
---|
416 | $y = $x;
|
---|
417 | $y = $x;
|
---|
418 | #print "WILL EXTERNAL UNTIE $ref\n";
|
---|
419 | untie $$ref;
|
---|
420 | $y = $x;
|
---|
421 | $y = $x;
|
---|
422 | $y = $x;
|
---|
423 | $y = $x;
|
---|
424 | #print "counter = $counter\n";
|
---|
425 |
|
---|
426 | print (($counter == 1) ? "ok\n" : "not ok\n");
|
---|
427 |
|
---|
428 | package Overlay;
|
---|
429 |
|
---|
430 | sub TIESCALAR
|
---|
431 | {
|
---|
432 | my $pkg = shift;
|
---|
433 | my ($ref, $val) = @_;
|
---|
434 | return bless [ $ref, $val ], $pkg;
|
---|
435 | }
|
---|
436 |
|
---|
437 | sub FETCH
|
---|
438 | {
|
---|
439 | my $self = shift;
|
---|
440 | my ($ref, $val) = @$self;
|
---|
441 | #print "WILL INTERNAL UNITE $ref\n";
|
---|
442 | $counter++;
|
---|
443 | untie $$ref;
|
---|
444 | return $val;
|
---|
445 | }
|
---|
446 | EXPECT
|
---|
447 | ok
|
---|
448 | ########
|
---|
449 |
|
---|
450 | # test SCALAR method
|
---|
451 | package TieScalar;
|
---|
452 |
|
---|
453 | sub TIEHASH {
|
---|
454 | my $pkg = shift;
|
---|
455 | bless { } => $pkg;
|
---|
456 | }
|
---|
457 |
|
---|
458 | sub STORE {
|
---|
459 | $_[0]->{$_[1]} = $_[2];
|
---|
460 | }
|
---|
461 |
|
---|
462 | sub FETCH {
|
---|
463 | $_[0]->{$_[1]}
|
---|
464 | }
|
---|
465 |
|
---|
466 | sub CLEAR {
|
---|
467 | %{ $_[0] } = ();
|
---|
468 | }
|
---|
469 |
|
---|
470 | sub SCALAR {
|
---|
471 | print "SCALAR\n";
|
---|
472 | return 0 if ! keys %{$_[0]};
|
---|
473 | sprintf "%i/%i", scalar keys %{$_[0]}, scalar keys %{$_[0]};
|
---|
474 | }
|
---|
475 |
|
---|
476 | package main;
|
---|
477 | tie my %h => "TieScalar";
|
---|
478 | $h{key1} = "val1";
|
---|
479 | $h{key2} = "val2";
|
---|
480 | print scalar %h, "\n";
|
---|
481 | %h = ();
|
---|
482 | print scalar %h, "\n";
|
---|
483 | EXPECT
|
---|
484 | SCALAR
|
---|
485 | 2/2
|
---|
486 | SCALAR
|
---|
487 | 0
|
---|
488 | ########
|
---|
489 |
|
---|
490 | # test scalar on tied hash when no SCALAR method has been given
|
---|
491 | package TieScalar;
|
---|
492 |
|
---|
493 | sub TIEHASH {
|
---|
494 | my $pkg = shift;
|
---|
495 | bless { } => $pkg;
|
---|
496 | }
|
---|
497 | sub STORE {
|
---|
498 | $_[0]->{$_[1]} = $_[2];
|
---|
499 | }
|
---|
500 | sub FETCH {
|
---|
501 | $_[0]->{$_[1]}
|
---|
502 | }
|
---|
503 | sub CLEAR {
|
---|
504 | %{ $_[0] } = ();
|
---|
505 | }
|
---|
506 | sub FIRSTKEY {
|
---|
507 | my $a = keys %{ $_[0] };
|
---|
508 | print "FIRSTKEY\n";
|
---|
509 | each %{ $_[0] };
|
---|
510 | }
|
---|
511 |
|
---|
512 | package main;
|
---|
513 | tie my %h => "TieScalar";
|
---|
514 |
|
---|
515 | if (!%h) {
|
---|
516 | print "empty\n";
|
---|
517 | } else {
|
---|
518 | print "not empty\n";
|
---|
519 | }
|
---|
520 |
|
---|
521 | $h{key1} = "val1";
|
---|
522 | print "not empty\n" if %h;
|
---|
523 | print "not empty\n" if %h;
|
---|
524 | print "-->\n";
|
---|
525 | my ($k,$v) = each %h;
|
---|
526 | print "<--\n";
|
---|
527 | print "not empty\n" if %h;
|
---|
528 | %h = ();
|
---|
529 | print "empty\n" if ! %h;
|
---|
530 | EXPECT
|
---|
531 | FIRSTKEY
|
---|
532 | empty
|
---|
533 | FIRSTKEY
|
---|
534 | not empty
|
---|
535 | FIRSTKEY
|
---|
536 | not empty
|
---|
537 | -->
|
---|
538 | FIRSTKEY
|
---|
539 | <--
|
---|
540 | not empty
|
---|
541 | FIRSTKEY
|
---|
542 | empty
|
---|
543 | ########
|
---|
544 | sub TIESCALAR { bless {} }
|
---|
545 | sub FETCH { my $x = 3.3; 1 if 0+$x; $x }
|
---|
546 | tie $h, "main";
|
---|
547 | print $h,"\n";
|
---|
548 | EXPECT
|
---|
549 | 3.3
|
---|