1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateBEGIN { 4*0Sstevel@tonic-gate chdir 't' if -d 't'; 5*0Sstevel@tonic-gate $dir = "self-$$"; 6*0Sstevel@tonic-gate $sep = "/"; 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate if ($^O eq 'MacOS') { 9*0Sstevel@tonic-gate $dir = ":" . $dir; 10*0Sstevel@tonic-gate $sep = ":"; 11*0Sstevel@tonic-gate } 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gate @INC = $dir; 14*0Sstevel@tonic-gate push @INC, '../lib'; 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate print "1..19\n"; 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gate # First we must set up some selfloader files 19*0Sstevel@tonic-gate mkdir $dir, 0755 or die "Can't mkdir $dir: $!"; 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate open(FOO, ">$dir${sep}Foo.pm") or die; 22*0Sstevel@tonic-gate print FOO <<'EOT'; 23*0Sstevel@tonic-gatepackage Foo; 24*0Sstevel@tonic-gateuse SelfLoader; 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gatesub new { bless {}, shift } 27*0Sstevel@tonic-gatesub foo; 28*0Sstevel@tonic-gatesub bar; 29*0Sstevel@tonic-gatesub bazmarkhianish; 30*0Sstevel@tonic-gatesub a; 31*0Sstevel@tonic-gatesub never; # declared but definition should never be read 32*0Sstevel@tonic-gate1; 33*0Sstevel@tonic-gate__DATA__ 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gatesub foo { shift; shift || "foo" }; 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gatesub bar { shift; shift || "bar" } 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gatesub bazmarkhianish { shift; shift || "baz" } 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gatepackage sheep; 42*0Sstevel@tonic-gatesub bleat { shift; shift || "baa" } 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate__END__ 45*0Sstevel@tonic-gatesub never { die "D'oh" } 46*0Sstevel@tonic-gateEOT 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate close(FOO); 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate open(BAR, ">$dir${sep}Bar.pm") or die; 51*0Sstevel@tonic-gate print BAR <<'EOT'; 52*0Sstevel@tonic-gatepackage Bar; 53*0Sstevel@tonic-gateuse SelfLoader; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate@ISA = 'Baz'; 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gatesub new { bless {}, shift } 58*0Sstevel@tonic-gatesub a; 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate1; 61*0Sstevel@tonic-gate__DATA__ 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gatesub a { 'a Bar'; } 64*0Sstevel@tonic-gatesub b { 'b Bar' } 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate__END__ DATA 67*0Sstevel@tonic-gatesub never { die "D'oh" } 68*0Sstevel@tonic-gateEOT 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate close(BAR); 71*0Sstevel@tonic-gate}; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gatepackage Baz; 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gatesub a { 'a Baz' } 77*0Sstevel@tonic-gatesub b { 'b Baz' } 78*0Sstevel@tonic-gatesub c { 'c Baz' } 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gatepackage main; 82*0Sstevel@tonic-gateuse Foo; 83*0Sstevel@tonic-gateuse Bar; 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate$foo = new Foo; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gateprint "not " unless $foo->foo eq 'foo'; # selfloaded first time 88*0Sstevel@tonic-gateprint "ok 1\n"; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gateprint "not " unless $foo->foo eq 'foo'; # regular call 91*0Sstevel@tonic-gateprint "ok 2\n"; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate# Try an undefined method 94*0Sstevel@tonic-gateeval { 95*0Sstevel@tonic-gate $foo->will_fail; 96*0Sstevel@tonic-gate}; 97*0Sstevel@tonic-gateif ($@ =~ /^Undefined subroutine/) { 98*0Sstevel@tonic-gate print "ok 3\n"; 99*0Sstevel@tonic-gate} else { 100*0Sstevel@tonic-gate print "not ok 3 $@\n"; 101*0Sstevel@tonic-gate} 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate# Used to be trouble with this 104*0Sstevel@tonic-gateeval { 105*0Sstevel@tonic-gate my $foo = new Foo; 106*0Sstevel@tonic-gate die "oops"; 107*0Sstevel@tonic-gate}; 108*0Sstevel@tonic-gateif ($@ =~ /oops/) { 109*0Sstevel@tonic-gate print "ok 4\n"; 110*0Sstevel@tonic-gate} else { 111*0Sstevel@tonic-gate print "not ok 4 $@\n"; 112*0Sstevel@tonic-gate} 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate# Pass regular expression variable to autoloaded function. This used 115*0Sstevel@tonic-gate# to go wrong in AutoLoader because it used regular expressions to generate 116*0Sstevel@tonic-gate# autoloaded filename. 117*0Sstevel@tonic-gate"foo" =~ /(\w+)/; 118*0Sstevel@tonic-gateprint "not " unless $1 eq 'foo'; 119*0Sstevel@tonic-gateprint "ok 5\n"; 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gateprint "not " unless $foo->bar($1) eq 'foo'; 122*0Sstevel@tonic-gateprint "ok 6\n"; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gateprint "not " unless $foo->bar($1) eq 'foo'; 125*0Sstevel@tonic-gateprint "ok 7\n"; 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gateprint "not " unless $foo->bazmarkhianish($1) eq 'foo'; 128*0Sstevel@tonic-gateprint "ok 8\n"; 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gateprint "not " unless $foo->bazmarkhianish($1) eq 'foo'; 131*0Sstevel@tonic-gateprint "ok 9\n"; 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate# Check nested packages inside __DATA__ 134*0Sstevel@tonic-gateprint "not " unless sheep::bleat() eq 'baa'; 135*0Sstevel@tonic-gateprint "ok 10\n"; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate# Now check inheritance: 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate$bar = new Bar; 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate# Before anything is SelfLoaded there is no declaration of Foo::b so we should 142*0Sstevel@tonic-gate# get Baz::b 143*0Sstevel@tonic-gateprint "not " unless $bar->b() eq 'b Baz'; 144*0Sstevel@tonic-gateprint "ok 11\n"; 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate# There is no Bar::c so we should get Baz::c 147*0Sstevel@tonic-gateprint "not " unless $bar->c() eq 'c Baz'; 148*0Sstevel@tonic-gateprint "ok 12\n"; 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate# This selfloads Bar::a because it is stubbed. It also stubs Bar::b as a side 151*0Sstevel@tonic-gate# effect 152*0Sstevel@tonic-gateprint "not " unless $bar->a() eq 'a Bar'; 153*0Sstevel@tonic-gateprint "ok 13\n"; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gateprint "not " unless $bar->b() eq 'b Bar'; 156*0Sstevel@tonic-gateprint "ok 14\n"; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gateprint "not " unless $bar->c() eq 'c Baz'; 159*0Sstevel@tonic-gateprint "ok 15\n"; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate# Check that __END__ is honoured 164*0Sstevel@tonic-gate# Try an subroutine that should never be noticed by selfloader 165*0Sstevel@tonic-gateeval { 166*0Sstevel@tonic-gate $foo->never; 167*0Sstevel@tonic-gate}; 168*0Sstevel@tonic-gateif ($@ =~ /^Undefined subroutine/) { 169*0Sstevel@tonic-gate print "ok 16\n"; 170*0Sstevel@tonic-gate} else { 171*0Sstevel@tonic-gate print "not ok 16 $@\n"; 172*0Sstevel@tonic-gate} 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate# Try to read from the data file handle 175*0Sstevel@tonic-gatemy $foodata = <Foo::DATA>; 176*0Sstevel@tonic-gateclose Foo::DATA; 177*0Sstevel@tonic-gateif (defined $foodata) { 178*0Sstevel@tonic-gate print "not ok 17 # $foodata\n"; 179*0Sstevel@tonic-gate} else { 180*0Sstevel@tonic-gate print "ok 17\n"; 181*0Sstevel@tonic-gate} 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate# Check that __END__ DATA is honoured 184*0Sstevel@tonic-gate# Try an subroutine that should never be noticed by selfloader 185*0Sstevel@tonic-gateeval { 186*0Sstevel@tonic-gate $bar->never; 187*0Sstevel@tonic-gate}; 188*0Sstevel@tonic-gateif ($@ =~ /^Undefined subroutine/) { 189*0Sstevel@tonic-gate print "ok 18\n"; 190*0Sstevel@tonic-gate} else { 191*0Sstevel@tonic-gate print "not ok 18 $@\n"; 192*0Sstevel@tonic-gate} 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate# Try to read from the data file handle 195*0Sstevel@tonic-gatemy $bardata = <Bar::DATA>; 196*0Sstevel@tonic-gateclose Bar::DATA; 197*0Sstevel@tonic-gateif ($bardata ne "sub never { die \"D'oh\" }\n") { 198*0Sstevel@tonic-gate print "not ok 19 # $bardata\n"; 199*0Sstevel@tonic-gate} else { 200*0Sstevel@tonic-gate print "ok 19\n"; 201*0Sstevel@tonic-gate} 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate# cleanup 204*0Sstevel@tonic-gateEND { 205*0Sstevel@tonic-gatereturn unless $dir && -d $dir; 206*0Sstevel@tonic-gateunlink "$dir${sep}Foo.pm", "$dir${sep}Bar.pm"; 207*0Sstevel@tonic-gatermdir "$dir"; 208*0Sstevel@tonic-gate} 209