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 @INC = '../lib'; 6*0Sstevel@tonic-gate} 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate# Can't use Test::Simple/More, they depend on Exporter. 9*0Sstevel@tonic-gatemy $test = 1; 10*0Sstevel@tonic-gatesub ok ($;$) { 11*0Sstevel@tonic-gate my($ok, $name) = @_; 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gate # You have to do it this way or VMS will get confused. 14*0Sstevel@tonic-gate printf "%sok %d%s\n", ($ok ? '' : 'not '), $test, 15*0Sstevel@tonic-gate (defined $name ? " - $name" : ''); 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate printf "# Failed test at line %d\n", (caller)[2] unless $ok; 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate $test++; 20*0Sstevel@tonic-gate return $ok; 21*0Sstevel@tonic-gate} 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gateprint "1..28\n"; 25*0Sstevel@tonic-gaterequire Exporter; 26*0Sstevel@tonic-gateok( 1, 'Exporter compiled' ); 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gateBEGIN { 30*0Sstevel@tonic-gate # Methods which Exporter says it implements. 31*0Sstevel@tonic-gate @Exporter_Methods = qw(import 32*0Sstevel@tonic-gate export_to_level 33*0Sstevel@tonic-gate require_version 34*0Sstevel@tonic-gate export_fail 35*0Sstevel@tonic-gate ); 36*0Sstevel@tonic-gate} 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gatepackage Testing; 40*0Sstevel@tonic-gaterequire Exporter; 41*0Sstevel@tonic-gate@ISA = qw(Exporter); 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate# Make sure Testing can do everything its supposed to. 44*0Sstevel@tonic-gateforeach my $meth (@::Exporter_Methods) { 45*0Sstevel@tonic-gate ::ok( Testing->can($meth), "subclass can $meth()" ); 46*0Sstevel@tonic-gate} 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate%EXPORT_TAGS = ( 49*0Sstevel@tonic-gate This => [qw(stuff %left)], 50*0Sstevel@tonic-gate That => [qw(Above the @wailing)], 51*0Sstevel@tonic-gate tray => [qw(Fasten $seatbelt)], 52*0Sstevel@tonic-gate ); 53*0Sstevel@tonic-gate@EXPORT = qw(lifejacket is); 54*0Sstevel@tonic-gate@EXPORT_OK = qw(under &your $seat); 55*0Sstevel@tonic-gate$VERSION = '1.05'; 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate::ok( Testing->require_version(1.05), 'require_version()' ); 58*0Sstevel@tonic-gateeval { Testing->require_version(1.11); 1 }; 59*0Sstevel@tonic-gate::ok( $@, 'require_version() fail' ); 60*0Sstevel@tonic-gate::ok( Testing->require_version(0), 'require_version(0)' ); 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gatesub lifejacket { 'lifejacket' } 63*0Sstevel@tonic-gatesub stuff { 'stuff' } 64*0Sstevel@tonic-gatesub Above { 'Above' } 65*0Sstevel@tonic-gatesub the { 'the' } 66*0Sstevel@tonic-gatesub Fasten { 'Fasten' } 67*0Sstevel@tonic-gatesub your { 'your' } 68*0Sstevel@tonic-gatesub under { 'under' } 69*0Sstevel@tonic-gateuse vars qw($seatbelt $seat @wailing %left); 70*0Sstevel@tonic-gate$seatbelt = 'seatbelt'; 71*0Sstevel@tonic-gate$seat = 'seat'; 72*0Sstevel@tonic-gate@wailing = qw(AHHHHHH); 73*0Sstevel@tonic-gate%left = ( left => "right" ); 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gateBEGIN {*is = \&Is}; 76*0Sstevel@tonic-gatesub Is { 'Is' }; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gateExporter::export_ok_tags; 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gatemy %tags = map { $_ => 1 } map { @$_ } values %EXPORT_TAGS; 81*0Sstevel@tonic-gatemy %exportok = map { $_ => 1 } @EXPORT_OK; 82*0Sstevel@tonic-gatemy $ok = 1; 83*0Sstevel@tonic-gateforeach my $tag (keys %tags) { 84*0Sstevel@tonic-gate $ok = exists $exportok{$tag}; 85*0Sstevel@tonic-gate} 86*0Sstevel@tonic-gate::ok( $ok, 'export_ok_tags()' ); 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gatepackage Foo; 90*0Sstevel@tonic-gateTesting->import; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate::ok( defined &lifejacket, 'simple import' ); 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gatemy $got = eval {&lifejacket}; 95*0Sstevel@tonic-gate::ok ( $@ eq "", 'check we can call the imported subroutine') 96*0Sstevel@tonic-gate or print STDERR "# \$\@ is $@\n"; 97*0Sstevel@tonic-gate::ok ( $got eq 'lifejacket', 'and that it gave the correct result') 98*0Sstevel@tonic-gate or print STDERR "# expected 'lifejacket', got " . 99*0Sstevel@tonic-gate (defined $got ? "'$got'" : "undef") . "\n"; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate# The string eval is important. It stops $Foo::{is} existing when 102*0Sstevel@tonic-gate# Testing->import is called. 103*0Sstevel@tonic-gate::ok( eval "defined &is", 104*0Sstevel@tonic-gate "Import a subroutine where exporter must create the typeglob" ); 105*0Sstevel@tonic-gatemy $got = eval "&is"; 106*0Sstevel@tonic-gate::ok ( $@ eq "", 'check we can call the imported autoloaded subroutine') 107*0Sstevel@tonic-gate or chomp ($@), print STDERR "# \$\@ is $@\n"; 108*0Sstevel@tonic-gate::ok ( $got eq 'Is', 'and that it gave the correct result') 109*0Sstevel@tonic-gate or print STDERR "# expected 'Is', got " . 110*0Sstevel@tonic-gate (defined $got ? "'$got'" : "undef") . "\n"; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gatepackage Bar; 114*0Sstevel@tonic-gatemy @imports = qw($seatbelt &Above stuff @wailing %left); 115*0Sstevel@tonic-gateTesting->import(@imports); 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate::ok( (!grep { eval "!defined $_" } map({ /^\w/ ? "&$_" : $_ } @imports)), 118*0Sstevel@tonic-gate 'import by symbols' ); 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gatepackage Yar; 122*0Sstevel@tonic-gatemy @tags = qw(:This :tray); 123*0Sstevel@tonic-gateTesting->import(@tags); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate::ok( (!grep { eval "!defined $_" } map { /^\w/ ? "&$_" : $_ } 126*0Sstevel@tonic-gate map { @$_ } @{$Testing::EXPORT_TAGS{@tags}}), 127*0Sstevel@tonic-gate 'import by tags' ); 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gatepackage Arrr; 131*0Sstevel@tonic-gateTesting->import(qw(!lifejacket)); 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate::ok( !defined &lifejacket, 'deny import by !' ); 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gatepackage Mars; 137*0Sstevel@tonic-gateTesting->import('/e/'); 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate::ok( (!grep { eval "!defined $_" } map { /^\w/ ? "&$_" : $_ } 140*0Sstevel@tonic-gate grep { /e/ } @Testing::EXPORT, @Testing::EXPORT_OK), 141*0Sstevel@tonic-gate 'import by regex'); 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gatepackage Venus; 145*0Sstevel@tonic-gateTesting->import('!/e/'); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate::ok( (!grep { eval "defined $_" } map { /^\w/ ? "&$_" : $_ } 148*0Sstevel@tonic-gate grep { /e/ } @Testing::EXPORT, @Testing::EXPORT_OK), 149*0Sstevel@tonic-gate 'deny import by regex'); 150*0Sstevel@tonic-gate::ok( !defined &lifejacket, 'further denial' ); 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gatepackage More::Testing; 154*0Sstevel@tonic-gate@ISA = qw(Exporter); 155*0Sstevel@tonic-gate$VERSION = 0; 156*0Sstevel@tonic-gateeval { More::Testing->require_version(0); 1 }; 157*0Sstevel@tonic-gate::ok(!$@, 'require_version(0) and $VERSION = 0'); 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gatepackage Yet::More::Testing; 161*0Sstevel@tonic-gate@ISA = qw(Exporter); 162*0Sstevel@tonic-gate$VERSION = 0; 163*0Sstevel@tonic-gateeval { Yet::More::Testing->require_version(10); 1 }; 164*0Sstevel@tonic-gate::ok($@ !~ /\(undef\)/, 'require_version(10) and $VERSION = 0'); 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gatemy $warnings; 168*0Sstevel@tonic-gateBEGIN { 169*0Sstevel@tonic-gate $SIG{__WARN__} = sub { $warnings = join '', @_ }; 170*0Sstevel@tonic-gate package Testing::Unused::Vars; 171*0Sstevel@tonic-gate @ISA = qw(Exporter); 172*0Sstevel@tonic-gate @EXPORT = qw(this $TODO that); 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate package Foo; 175*0Sstevel@tonic-gate Testing::Unused::Vars->import; 176*0Sstevel@tonic-gate} 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate::ok( !$warnings, 'Unused variables can be exported without warning' ) || 179*0Sstevel@tonic-gate print "# $warnings\n"; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gatepackage Moving::Target; 182*0Sstevel@tonic-gate@ISA = qw(Exporter); 183*0Sstevel@tonic-gate@EXPORT_OK = qw (foo); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gatesub foo {"foo"}; 186*0Sstevel@tonic-gatesub bar {"bar"}; 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gatepackage Moving::Target::Test; 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gateMoving::Target->import (foo); 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate::ok (foo eq "foo", "imported foo before EXPORT_OK changed"); 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gatepush @Moving::Target::EXPORT_OK, 'bar'; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gateMoving::Target->import (bar); 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate::ok (bar eq "bar", "imported bar after EXPORT_OK changed"); 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gatepackage The::Import; 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gateuse Exporter 'import'; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gateeval { import() }; 205*0Sstevel@tonic-gate::ok(\&import == \&Exporter::import, "imported the import routine"); 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate@EXPORT = qw( wibble ); 208*0Sstevel@tonic-gatesub wibble {return "wobble"}; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gatepackage Use::The::Import; 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gateThe::Import->import; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gatemy $val = eval { wibble() }; 215*0Sstevel@tonic-gate::ok($val eq "wobble", "exported importer worked"); 216*0Sstevel@tonic-gate 217