xref: /openbsd/gnu/usr.bin/perl/dist/base/t/fields-5_8_0.t (revision 5759b3d2)
1#!/usr/bin/perl -w
2
3# We skip this on 5.9.0 and up since pseudohashes were removed and a lot of
4# it won't work.
5if( $] >= 5.009 ) {
6    print "1..0 # skip pseudo-hashes removed in 5.9.0\n";
7    exit;
8}
9
10
11my $w;
12
13BEGIN {
14   $SIG{__WARN__} = sub {
15       if ($_[0] =~ /^Hides field 'b1' in base class/) {
16           $w++;
17       }
18       else {
19	 print STDERR $_[0];
20       }
21   };
22}
23
24use strict;
25our $DEBUG;
26
27package B1;
28use fields qw(b1 b2 b3);
29
30package B2;
31use fields '_b1';
32use fields qw(b1 _b2 b2);
33
34sub new { bless [], shift }
35
36package D1;
37use base 'B1';
38use fields qw(d1 d2 d3);
39
40package D2;
41use base 'B1';
42use fields qw(_d1 _d2);
43use fields qw(d1 d2);
44
45package D3;
46use base 'B2';
47use fields qw(b1 d1 _b1 _d1);  # hide b1
48
49package D4;
50use base 'D3';
51use fields qw(_d3 d3);
52
53package M;
54sub m {}
55
56package D5;
57use base qw(M B2);
58
59package Foo::Bar;
60use base 'B1';
61
62package Foo::Bar::Baz;
63use base 'Foo::Bar';
64use fields qw(foo bar baz);
65
66# Test repeatability for when modules get reloaded.
67package B1;
68use fields qw(b1 b2 b3);
69
70package D3;
71use base 'B2';
72use fields qw(b1 d1 _b1 _d1);  # hide b1
73
74package main;
75
76sub fstr {
77    local $SIG{__WARN__} = sub {
78        return if $_[0] =~ /^Pseudo-hashes are deprecated/
79    };
80
81   my $h = shift;
82   my @tmp;
83   for my $k (sort {$h->{$a} <=> $h->{$b}} keys %$h) {
84	my $v = $h->{$k};
85        push(@tmp, "$k:$v");
86   }
87   my $str = join(",", @tmp);
88   print "$h => $str\n" if $DEBUG;
89   $str;
90}
91
92my %expect = (
93    B1 => "b1:1,b2:2,b3:3",
94    B2 => "_b1:1,b1:2,_b2:3,b2:4",
95    D1 => "b1:1,b2:2,b3:3,d1:4,d2:5,d3:6",
96    D2 => "b1:1,b2:2,b3:3,_d1:4,_d2:5,d1:6,d2:7",
97    D3 => "b2:4,b1:5,d1:6,_b1:7,_d1:8",
98    D4 => "b2:4,b1:5,d1:6,_d3:9,d3:10",
99    D5 => "b1:2,b2:4",
100    'Foo::Bar::Baz' => 'b1:1,b2:2,b3:3,foo:4,bar:5,baz:6',
101);
102
103print "1..", int(keys %expect)+20, "\n";
104my $testno = 0;
105while (my($class, $exp) = each %expect) {
106   no strict 'refs';
107   my $fstr = fstr(\%{$class."::FIELDS"});
108   print "EXP: $exp\nGOT: $fstr\nnot " unless $fstr eq $exp;
109   print "ok ", ++$testno, "\n";
110}
111
112# Did we get the appropriate amount of warnings?
113print "not " unless $w == 1;
114print "ok ", ++$testno, "\n";
115
116# A simple object creation and AVHV attribute access test
117my B2 $obj1 = D3->new;
118$obj1->{b1} = "B2";
119my D3 $obj2 = $obj1;
120$obj2->{b1} = "D3";
121
122print "not " unless $obj1->[2] eq "B2" && $obj1->[5] eq "D3";
123print "ok ", ++$testno, "\n";
124
125# We should get compile time failures field name typos
126eval q(my D3 $obj3 = $obj2; $obj3->{notthere} = "");
127print "not " unless $@ && $@ =~ /^No such pseudo-hash field "notthere"/;
128print "ok ", ++$testno, "\n";
129
130# Slices
131@$obj1{"_b1", "b1"} = (17, 29);
132print "not " unless "@$obj1[1,2]" eq "17 29";
133print "ok ", ++$testno, "\n";
134@$obj1[1,2] = (44,28);
135print "not " unless "@$obj1{'b1','_b1','b1'}" eq "28 44 28";
136print "ok ", ++$testno, "\n";
137
138{
139    local $SIG{__WARN__} = sub {
140        return if $_[0] =~ /^Pseudo-hashes are deprecated/
141    };
142
143    my $ph = fields::phash(a => 1, b => 2, c => 3);
144    print "not " unless fstr($ph) eq 'a:1,b:2,c:3';
145    print "ok ", ++$testno, "\n";
146
147    $ph = fields::phash([qw/a b c/], [1, 2, 3]);
148    print "not " unless fstr($ph) eq 'a:1,b:2,c:3';
149    print "ok ", ++$testno, "\n";
150
151    $ph = fields::phash([qw/a b c/], [1]);
152    print "not " if exists $ph->{b} or exists $ph->{c} or !exists $ph->{a};
153    print "ok ", ++$testno, "\n";
154
155    eval '$ph = fields::phash("odd")';
156    print "not " unless $@ && $@ =~ /^Odd number of/;
157    print "ok ", ++$testno, "\n";
158}
159
160#fields::_dump();
161
162# check if fields autovivify
163{
164    package Foo;
165    use fields qw(foo bar);
166    sub new { bless [], $_[0]; }
167
168    package main;
169    my Foo $a = Foo->new();
170    $a->{foo} = ['a', 'ok ' . ++$testno, 'c'];
171    $a->{bar} = { A => 'ok ' . ++$testno };
172    print $a->{foo}[1], "\n";
173    print $a->{bar}->{A}, "\n";
174}
175
176# check if fields autovivify
177{
178    package Bar;
179    use fields qw(foo bar);
180    sub new { return fields::new($_[0]) }
181
182    package main;
183    my Bar $a = Bar::->new();
184    $a->{foo} = ['a', 'ok ' . ++$testno, 'c'];
185    $a->{bar} = { A => 'ok ' . ++$testno };
186    print $a->{foo}[1], "\n";
187    print $a->{bar}->{A}, "\n";
188}
189
190# Test Inverse of $VERSION bug base.pm should not clobber existing $VERSION
191package Has::Version;
192
193BEGIN { $Has::Version::VERSION = '42' };
194
195package Test::Version2;
196
197use base qw(Has::Version);
198print "#$Has::Version::VERSION\nnot " unless $Has::Version::VERSION eq '42';
199print "ok ", ++$testno ," # Has::Version\n";
200
201package main;
202
203my $eval1 = q{
204  {
205    package Eval1;
206    {
207      package Eval2;
208      use base 'Eval1';
209      $Eval2::VERSION = "1.02";
210    }
211    $Eval1::VERSION = "1.01";
212  }
213};
214
215eval $eval1;
216printf "# %s\nnot ", $@ if $@;
217print "ok ", ++$testno ," # eval1\n";
218
219print "# $Eval1::VERSION\nnot " unless $Eval1::VERSION == 1.01;
220print "ok ", ++$testno ," # Eval1::VERSION\n";
221
222print "# $Eval2::VERSION\nnot " unless $Eval2::VERSION == 1.02;
223print "ok ", ++$testno ," # Eval2::VERSION\n";
224
225
226eval q{use base reallyReAlLyNotexists;};
227print "not " unless $@;
228print "ok ", ++$testno, " # really not I\n";
229
230eval q{use base reallyReAlLyNotexists;};
231print "not " unless $@;
232print "ok ", ++$testno, " # really not II\n";
233
234BEGIN { $Has::Version_0::VERSION = 0 }
235
236package Test::Version3;
237
238use base qw(Has::Version_0);
239print "#$Has::Version_0::VERSION\nnot " unless $Has::Version_0::VERSION == 0;
240print "ok ", ++$testno ," # Version_0\n";
241
242