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