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