xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/AutoLoader.t (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!./perl -w
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gateBEGIN {
4*0Sstevel@tonic-gate    chdir 't' if -d 't';
5*0Sstevel@tonic-gate	@INC = '../lib';
6*0Sstevel@tonic-gate}
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gateuse strict;
9*0Sstevel@tonic-gateuse File::Spec;
10*0Sstevel@tonic-gateuse File::Path;
11*0Sstevel@tonic-gate
12*0Sstevel@tonic-gatemy $dir;
13*0Sstevel@tonic-gateBEGIN
14*0Sstevel@tonic-gate{
15*0Sstevel@tonic-gate	$dir = File::Spec->catdir( "auto-$$" );
16*0Sstevel@tonic-gate	unshift @INC, $dir;
17*0Sstevel@tonic-gate}
18*0Sstevel@tonic-gate
19*0Sstevel@tonic-gateuse Test::More tests => 17;
20*0Sstevel@tonic-gate
21*0Sstevel@tonic-gate# First we must set up some autoloader files
22*0Sstevel@tonic-gatemy $fulldir = File::Spec->catdir( $dir, 'auto', 'Foo' );
23*0Sstevel@tonic-gatemkpath( $fulldir ) or die "Can't mkdir '$fulldir': $!";
24*0Sstevel@tonic-gate
25*0Sstevel@tonic-gateopen(FOO, '>', File::Spec->catfile( $fulldir, 'foo.al' ))
26*0Sstevel@tonic-gate	or die "Can't open foo file: $!";
27*0Sstevel@tonic-gateprint FOO <<'EOT';
28*0Sstevel@tonic-gatepackage Foo;
29*0Sstevel@tonic-gatesub foo { shift; shift || "foo" }
30*0Sstevel@tonic-gate1;
31*0Sstevel@tonic-gateEOT
32*0Sstevel@tonic-gateclose(FOO);
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gateopen(BAR, '>', File::Spec->catfile( $fulldir, 'bar.al' ))
35*0Sstevel@tonic-gate	or die "Can't open bar file: $!";
36*0Sstevel@tonic-gateprint BAR <<'EOT';
37*0Sstevel@tonic-gatepackage Foo;
38*0Sstevel@tonic-gatesub bar { shift; shift || "bar" }
39*0Sstevel@tonic-gate1;
40*0Sstevel@tonic-gateEOT
41*0Sstevel@tonic-gateclose(BAR);
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gateopen(BAZ, '>', File::Spec->catfile( $fulldir, 'bazmarkhian.al' ))
44*0Sstevel@tonic-gate	or die "Can't open bazmarkhian file: $!";
45*0Sstevel@tonic-gateprint BAZ <<'EOT';
46*0Sstevel@tonic-gatepackage Foo;
47*0Sstevel@tonic-gatesub bazmarkhianish { shift; shift || "baz" }
48*0Sstevel@tonic-gate1;
49*0Sstevel@tonic-gateEOT
50*0Sstevel@tonic-gateclose(BAZ);
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gateopen(BLECH, '>', File::Spec->catfile( $fulldir, 'blechanawilla.al' ))
53*0Sstevel@tonic-gate       or die "Can't open blech file: $!";
54*0Sstevel@tonic-gateprint BLECH <<'EOT';
55*0Sstevel@tonic-gatepackage Foo;
56*0Sstevel@tonic-gatesub blechanawilla { compilation error (
57*0Sstevel@tonic-gateEOT
58*0Sstevel@tonic-gateclose(BLECH);
59*0Sstevel@tonic-gate
60*0Sstevel@tonic-gate# This is just to keep the old SVR3 systems happy; they may fail
61*0Sstevel@tonic-gate# to find the above file so we duplicate it where they should find it.
62*0Sstevel@tonic-gateopen(BLECH, '>', File::Spec->catfile( $fulldir, 'blechanawil.al' ))
63*0Sstevel@tonic-gate       or die "Can't open blech file: $!";
64*0Sstevel@tonic-gateprint BLECH <<'EOT';
65*0Sstevel@tonic-gatepackage Foo;
66*0Sstevel@tonic-gatesub blechanawilla { compilation error (
67*0Sstevel@tonic-gateEOT
68*0Sstevel@tonic-gateclose(BLECH);
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate# Let's define the package
71*0Sstevel@tonic-gatepackage Foo;
72*0Sstevel@tonic-gaterequire AutoLoader;
73*0Sstevel@tonic-gateAutoLoader->import( 'AUTOLOAD' );
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gatesub new { bless {}, shift };
76*0Sstevel@tonic-gatesub foo;
77*0Sstevel@tonic-gatesub bar;
78*0Sstevel@tonic-gatesub bazmarkhianish;
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gatepackage main;
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gatemy $foo = new Foo;
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gatemy $result = $foo->can( 'foo' );
85*0Sstevel@tonic-gateok( $result,               'can() first time' );
86*0Sstevel@tonic-gateis( $foo->foo, 'foo', 'autoloaded first time' );
87*0Sstevel@tonic-gateis( $foo->foo, 'foo', 'regular call' );
88*0Sstevel@tonic-gateis( $result,   \&Foo::foo, 'can() returns ref to regular installed sub' );
89*0Sstevel@tonic-gate
90*0Sstevel@tonic-gateeval {
91*0Sstevel@tonic-gate    $foo->will_fail;
92*0Sstevel@tonic-gate};
93*0Sstevel@tonic-gatelike( $@, qr/^Can't locate/, 'undefined method' );
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate$result = $foo->can( 'will_fail' );
96*0Sstevel@tonic-gateok( ! $result,               'can() should fail on undefined methods' );
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate# Used to be trouble with this
99*0Sstevel@tonic-gateeval {
100*0Sstevel@tonic-gate    my $foo = new Foo;
101*0Sstevel@tonic-gate    die "oops";
102*0Sstevel@tonic-gate};
103*0Sstevel@tonic-gatelike( $@, qr/oops/, 'indirect method call' );
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gate# Pass regular expression variable to autoloaded function.  This used
106*0Sstevel@tonic-gate# to go wrong because AutoLoader used regular expressions to generate
107*0Sstevel@tonic-gate# autoloaded filename.
108*0Sstevel@tonic-gate'foo' =~ /(\w+)/;
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gateis( $foo->bar($1), 'foo', 'autoloaded method should not stomp match vars' );
111*0Sstevel@tonic-gateis( $foo->bar($1), 'foo', '(again)' );
112*0Sstevel@tonic-gateis( $foo->bazmarkhianish($1), 'foo', 'for any method call' );
113*0Sstevel@tonic-gateis( $foo->bazmarkhianish($1), 'foo', '(again)' );
114*0Sstevel@tonic-gate
115*0Sstevel@tonic-gate# Used to retry long subnames with shorter filenames on any old
116*0Sstevel@tonic-gate# exception, including compilation error.  Now AutoLoader only
117*0Sstevel@tonic-gate# tries shorter filenames if it can't find the long one.
118*0Sstevel@tonic-gateeval {
119*0Sstevel@tonic-gate  $foo->blechanawilla;
120*0Sstevel@tonic-gate};
121*0Sstevel@tonic-gatelike( $@, qr/syntax error/, 'require error propagates' );
122*0Sstevel@tonic-gate
123*0Sstevel@tonic-gate# test recursive autoloads
124*0Sstevel@tonic-gateopen(F, '>', File::Spec->catfile( $fulldir, 'a.al'))
125*0Sstevel@tonic-gate	or die "Cannot make 'a' file: $!";
126*0Sstevel@tonic-gateprint F <<'EOT';
127*0Sstevel@tonic-gatepackage Foo;
128*0Sstevel@tonic-gateBEGIN { b() }
129*0Sstevel@tonic-gatesub a { ::ok( 1, 'adding a new autoloaded method' ); }
130*0Sstevel@tonic-gate1;
131*0Sstevel@tonic-gateEOT
132*0Sstevel@tonic-gateclose(F);
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gateopen(F, '>', File::Spec->catfile( $fulldir, 'b.al'))
135*0Sstevel@tonic-gate	or die "Cannot make 'b' file: $!";
136*0Sstevel@tonic-gateprint F <<'EOT';
137*0Sstevel@tonic-gatepackage Foo;
138*0Sstevel@tonic-gatesub b { ::ok( 1, 'adding a new autoloaded method' ) }
139*0Sstevel@tonic-gate1;
140*0Sstevel@tonic-gateEOT
141*0Sstevel@tonic-gateclose(F);
142*0Sstevel@tonic-gateFoo::a();
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gatepackage Bar;
145*0Sstevel@tonic-gateAutoLoader->import();
146*0Sstevel@tonic-gate::ok( ! defined &AUTOLOAD, 'AutoLoader should not export AUTOLOAD by default' );
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gatepackage Foo;
149*0Sstevel@tonic-gateAutoLoader->unimport();
150*0Sstevel@tonic-gateeval { Foo->baz() };
151*0Sstevel@tonic-gate::like( $@, qr/locate object method "baz"/,
152*0Sstevel@tonic-gate	'unimport() should remove imported AUTOLOAD()' );
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gatepackage Baz;
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gatesub AUTOLOAD { 'i am here' }
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gateAutoLoader->import();
159*0Sstevel@tonic-gateAutoLoader->unimport();
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate::is( Baz->AUTOLOAD(), 'i am here', '... but not non-imported AUTOLOAD()' );
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gatepackage main;
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate# cleanup
166*0Sstevel@tonic-gateEND {
167*0Sstevel@tonic-gate	return unless $dir && -d $dir;
168*0Sstevel@tonic-gate	rmtree $dir;
169*0Sstevel@tonic-gate}
170