diff options
author | markm <markm@FreeBSD.org> | 2002-03-16 20:14:31 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 2002-03-16 20:14:31 +0000 |
commit | df2204f4cdf3fa64a0b2d36a33a3094944c9c4ab (patch) | |
tree | 1a8c861937509eca308e49c4f8940a22a169caf0 /contrib/perl5/t/lib | |
parent | b878a8b4fc512ca76116a7012802d385208857c3 (diff) | |
parent | e624907b04b90475ab8fb7b93c15320db1969c09 (diff) | |
download | FreeBSD-src-df2204f4cdf3fa64a0b2d36a33a3094944c9c4ab.zip FreeBSD-src-df2204f4cdf3fa64a0b2d36a33a3094944c9c4ab.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r92444,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/perl5/t/lib')
-rwxr-xr-x | contrib/perl5/t/lib/b.t | 163 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/cgi-esc.t | 56 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/cgi-pretty.t | 41 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/class-struct.t | 66 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/ftmp-mktemp.t | 114 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/ftmp-posix.t | 81 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/ftmp-security.t | 140 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/ftmp-tempfile.t | 145 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/gol-oo.t | 26 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/peek.t | 312 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/selfloader.t | 201 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/syslog.t | 59 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/tie-refhash.t | 305 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/tie-splice.t | 17 | ||||
-rwxr-xr-x | contrib/perl5/t/lib/tie-substrhash.t | 111 |
15 files changed, 1837 insertions, 0 deletions
diff --git a/contrib/perl5/t/lib/b.t b/contrib/perl5/t/lib/b.t new file mode 100755 index 0000000..22156c2 --- /dev/null +++ b/contrib/perl5/t/lib/b.t @@ -0,0 +1,163 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + if ($^O eq 'MacOS') { + @INC = qw(: ::lib ::macos:lib); + } else { + @INC = '.'; + push @INC, '../lib'; + } +} + +$| = 1; +use warnings; +use strict; +use Config; + +print "1..15\n"; + +my $test = 1; + +sub ok { print "ok $test\n"; $test++ } + +use B::Deparse; +my $deparse = B::Deparse->new() or print "not "; +ok; + +print "not " if "{\n 1;\n}" ne $deparse->coderef2text(sub {1}); +ok; + +print "not " if "{\n '???';\n 2;\n}" ne + $deparse->coderef2text(sub {1;2}); +ok; + +print "not " if "{\n \$test /= 2 if ++\$test;\n}" ne + $deparse->coderef2text(sub {++$test and $test/=2;}); +ok; +{ +my $a = <<'EOF'; +{ + $test = sub : lvalue { + my $x; + } + ; +} +EOF +chomp $a; +print "not " if $deparse->coderef2text(sub{$test = sub : lvalue{my $x}}) ne $a; +ok; + +$a =~ s/lvalue/method/; +print "not " if $deparse->coderef2text(sub{$test = sub : method{my $x}}) ne $a; +ok; + +$a =~ s/method/locked method/; +print "not " if $deparse->coderef2text(sub{$test = sub : method locked {my $x}}) + ne $a; +ok; +} + +my $a; +my $Is_VMS = $^O eq 'VMS'; +my $Is_MacOS = $^O eq 'MacOS'; + +my $path = join " ", map { qq["-I$_"] } @INC; +my $redir = $Is_MacOS ? "" : "2>&1"; + +$a = `$^X $path "-MO=Deparse" -anle 1 $redir`; +$a =~ s/-e syntax OK\n//g; +$a =~ s{\\340\\242}{\\s} if (ord("\\") == 224); # EBCDIC, cp 1047 or 037 +$a =~ s{\\274\\242}{\\s} if (ord("\\") == 188); # $^O eq 'posix-bc' +$b = <<'EOF'; + +LINE: while (defined($_ = <ARGV>)) { + chomp $_; + @F = split(/\s+/, $_, 0); + '???'; +} + +EOF +print "# [$a]\n\# vs\n# [$b]\nnot " if $a ne $b; +ok; + +#6 +$a = `$^X $path "-MO=Debug" -e 1 $redir`; +print "not " unless $a =~ +/\bLISTOP\b.*\bOP\b.*\bCOP\b.*\bOP\b/s; +ok; + +#7 +$a = `$^X $path "-MO=Terse" -e 1 $redir`; +print "not " unless $a =~ +/\bLISTOP\b.*leave.*\n OP\b.*enter.*\n COP\b.*nextstate.*\n OP\b.*null/s; +ok; + +$a = `$^X $path "-MO=Terse" -ane "s/foo/bar/" $redir`; +$a =~ s/\(0x[^)]+\)//g; +$a =~ s/\[[^\]]+\]//g; +$a =~ s/-e syntax OK//; +$a =~ s/[^a-z ]+//g; +$a =~ s/\s+/ /g; +$a =~ s/\b(s|foo|bar|ullsv)\b\s?//g; +$a =~ s/^\s+//; +$a =~ s/\s+$//; +my $is_thread = $Config{use5005threads} && $Config{use5005threads} eq 'define'; +if ($is_thread) { + $b=<<EOF; +leave enter nextstate label leaveloop enterloop null and defined null +threadsv readline gv lineseq nextstate aassign null pushmark split pushre +threadsv const null pushmark rvav gv nextstate subst const unstack nextstate +EOF +} else { + $b=<<EOF; +leave enter nextstate label leaveloop enterloop null and defined null +null gvsv readline gv lineseq nextstate aassign null pushmark split pushre +null gvsv const null pushmark rvav gv nextstate subst const unstack nextstate +EOF +} +$b=~s/\n/ /g;$b=~s/\s+/ /g; +$b =~ s/\s+$//; +print "# [$a]\n# vs\n# [$b]\nnot " if $a ne $b; +ok; + +chomp($a = `$^X $path "-MB::Stash" "-Mwarnings" -e1`); +$a = join ',', sort split /,/, $a; +$a =~ s/-uWin32,// if $^O eq 'MSWin32'; +$a =~ s/-u(Cwd|File|File::Copy|OS2),//g if $^O eq 'os2'; +$a =~ s/-uCwd,// if $^O eq 'cygwin'; +if ($Config{static_ext} eq ' ') { + $b = '-uCarp,-uCarp::Heavy,-uDB,-uExporter,-uExporter::Heavy,-uattributes,' + . '-umain,-uwarnings'; + if (ord('A') == 193) { # EBCDIC sort order is qw(a A) not qw(A a) + $b = join ',', sort split /,/, $b; + } + print "# [$a] vs [$b]\nnot " if $a ne $b; + ok; +} else { + print "ok $test # skipped: one or more static extensions\n"; $test++; +} + +if ($is_thread) { + print "# use5005threads: test $test skipped\n"; +} else { + $a = `$^X $path "-MO=Showlex" -e "my %one" $redir`; + if (ord('A') != 193) { # ASCIIish + print "# [$a]\nnot " unless $a =~ /sv_undef.*PVNV.*%one.*sv_undef.*HV/s; + } + else { # EBCDICish C<1: PVNV (0x1a7ede34) "%\226\225\205"> + print "# [$a]\nnot " unless $a =~ /sv_undef.*PVNV.*%\\[0-9].*sv_undef.*HV/s; + } +} +ok; + +# Bug 20001204.07 +{ +my $foo = $deparse->coderef2text(sub { { 234; }}); +# Constants don't get optimised here. +print "not " unless $foo =~ /{.*{.*234;.*}.*}/sm; +ok; +$foo = $deparse->coderef2text(sub { { 234; } continue { 123; } }); +print "not " unless $foo =~ /{.*{.*234;.*}.*continue.*{.*123.*}/sm; +ok; +} diff --git a/contrib/perl5/t/lib/cgi-esc.t b/contrib/perl5/t/lib/cgi-esc.t new file mode 100755 index 0000000..f0471cf --- /dev/null +++ b/contrib/perl5/t/lib/cgi-esc.t @@ -0,0 +1,56 @@ +#!/usr/local/bin/perl -w + +BEGIN { + chdir('t') if -d 't'; + @INC = '../lib'; +} + +# Test ability to escape() and unescape() punctuation characters +# except for qw(- . _). +######################### We start with some black magic to print on failure. +use lib '../blib/lib','../blib/arch'; + +BEGIN {$| = 1; print "1..59\n"; } +END {print "not ok 1\n" unless $loaded;} +use Config; +use CGI::Util qw(escape unescape); +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# util +sub test { + local($^W) = 0; + my($num, $true,$msg) = @_; + print($true ? "ok $num\n" : "not ok $num $msg\n"); +} + +# ASCII order, ASCII codepoints, ASCII repertoire + +my %punct = ( + ' ' => '20', '!' => '21', '"' => '22', '#' => '23', + '$' => '24', '%' => '25', '&' => '26', '\'' => '27', + '(' => '28', ')' => '29', '*' => '2A', '+' => '2B', + ',' => '2C', '/' => '2F', # '-' => '2D', '.' => '2E' + ':' => '3A', ';' => '3B', '<' => '3C', '=' => '3D', + '>' => '3E', '?' => '3F', '[' => '5B', '\\' => '5C', + ']' => '5D', '^' => '5E', '`' => '60', # '_' => '5F', + '{' => '7B', '|' => '7C', '}' => '7D', '~' => '7E', + ); + +# The sort order may not be ASCII on EBCDIC machines: + +my $i = 1; + +foreach(sort(keys(%punct))) { + $i++; + my $escape = "AbC\%$punct{$_}dEF"; + my $cgi_escape = escape("AbC$_" . "dEF"); + test($i, $escape eq $cgi_escape , "# $escape ne $cgi_escape"); + $i++; + my $unescape = "AbC$_" . "dEF"; + my $cgi_unescape = unescape("AbC\%$punct{$_}dEF"); + test($i, $unescape eq $cgi_unescape , "# $unescape ne $cgi_unescape"); +} + diff --git a/contrib/perl5/t/lib/cgi-pretty.t b/contrib/perl5/t/lib/cgi-pretty.t new file mode 100755 index 0000000..14f6447 --- /dev/null +++ b/contrib/perl5/t/lib/cgi-pretty.t @@ -0,0 +1,41 @@ +#!/usr/local/bin/perl -w + +BEGIN { + chdir('t') if -d 't'; + @INC = '../lib'; +} + +# Test ability to retrieve HTTP request info +######################### We start with some black magic to print on failure. +use lib '../blib/lib','../blib/arch'; + +BEGIN {$| = 1; print "1..5\n"; } +END {print "not ok 1\n" unless $loaded;} +use CGI::Pretty (':standard','-no_debug','*h3','start_table'); +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# util +sub test { + local($^W) = 0; + my($num, $true,$msg) = @_; + print($true ? "ok $num\n" : "not ok $num $msg\n"); +} + +# all the automatic tags +test(2,h1() eq '<h1>',"single tag"); +test(3,ol(li('fred'),li('ethel')) eq "<ol>\n\t<li>\n\t\tfred\n\t</li>\n\t <li>\n\t\tethel\n\t</li>\n</ol>\n","basic indentation"); +test(4,p('hi',pre('there'),'frog') eq +'<p> + hi <pre>there</pre> + frog +</p> +',"<pre> tags"); +test(5,p('hi',a({-href=>'frog'},'there'),'frog') eq +'<p> + hi <a href="frog">there</a> + frog +</p> +',"as-is"); diff --git a/contrib/perl5/t/lib/class-struct.t b/contrib/perl5/t/lib/class-struct.t new file mode 100755 index 0000000..26505ba --- /dev/null +++ b/contrib/perl5/t/lib/class-struct.t @@ -0,0 +1,66 @@ +#!./perl -w + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; +} + +print "1..8\n"; + +package aClass; + +sub new { bless {}, shift } + +sub meth { 42 } + +package MyObj; + +use Class::Struct; +use Class::Struct 'struct'; # test out both forms + +use Class::Struct SomeClass => { SomeElem => '$' }; + +struct( s => '$', a => '@', h => '%', c => 'aClass' ); + +my $obj = MyObj->new; + +$obj->s('foo'); + +print "not " unless $obj->s() eq 'foo'; +print "ok 1\n"; + +my $arf = $obj->a; + +print "not " unless ref $arf eq 'ARRAY'; +print "ok 2\n"; + +$obj->a(2, 'secundus'); + +print "not " unless $obj->a(2) eq 'secundus'; +print "ok 3\n"; + +my $hrf = $obj->h; + +print "not " unless ref $hrf eq 'HASH'; +print "ok 4\n"; + +$obj->h('x', 10); + +print "not " unless $obj->h('x') == 10; +print "ok 5\n"; + +my $orf = $obj->c; + +print "not " unless ref $orf eq 'aClass'; +print "ok 6\n"; + +print "not " unless $obj->c->meth() == 42; +print "ok 7\n"; + +my $obk = SomeClass->new(); + +$obk->SomeElem(123); + +print "not " unless $obk->SomeElem() == 123; +print "ok 8\n"; + diff --git a/contrib/perl5/t/lib/ftmp-mktemp.t b/contrib/perl5/t/lib/ftmp-mktemp.t new file mode 100755 index 0000000..b0a7872 --- /dev/null +++ b/contrib/perl5/t/lib/ftmp-mktemp.t @@ -0,0 +1,114 @@ +#!/usr/bin/perl -w + +# Test for mktemp family of commands in File::Temp +# Use STANDARD safe level for these tests + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Test; import Test; + plan(tests => 9); +} + +use strict; + +use File::Spec; +use File::Path; +use File::Temp qw/ :mktemp unlink0 /; + +ok(1); + +# MKSTEMP - test + +# Create file in temp directory +my $template = File::Spec->catfile(File::Spec->tmpdir, 'wowserXXXX'); + +(my $fh, $template) = mkstemp($template); + +print "# MKSTEMP: FH is $fh File is $template fileno=".fileno($fh)."\n"; +# Check if the file exists +ok( (-e $template) ); + +# Autoflush +$fh->autoflush(1) if $] >= 5.006; + +# Try printing something to the file +my $string = "woohoo\n"; +print $fh $string; + +# rewind the file +ok(seek( $fh, 0, 0)); + +# Read from the file +my $line = <$fh>; + +# compare with previous string +ok($string, $line); + +# Tidy up +# This test fails on Windows NT since it seems that the size returned by +# stat(filehandle) does not always equal the size of the stat(filename) +# This must be due to caching. In particular this test writes 7 bytes +# to the file which are not recognised by stat(filename) +# Simply waiting 3 seconds seems to be enough for the system to update + +if ($^O eq 'MSWin32') { + sleep 3; +} +my $status = unlink0($fh, $template); +if ($status) { + ok( $status ); +} else { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); +} + +# MKSTEMPS +# File with suffix. This is created in the current directory so +# may be problematic on NFS + +$template = "suffixXXXXXX"; +my $suffix = ".dat"; + +($fh, my $fname) = mkstemps($template, $suffix); + +print "# MKSTEMPS: File is $template -> $fname fileno=".fileno($fh)."\n"; +# Check if the file exists +ok( (-e $fname) ); + +# This fails if you are running on NFS +# If this test fails simply skip it rather than doing a hard failure +$status = unlink0($fh, $fname); + +if ($status) { + ok($status); +} else { + skip("Skip test failed probably due to cwd being on NFS",1) +} + +# MKDTEMP +# Temp directory + +$template = File::Spec->catdir(File::Spec->tmpdir, 'tmpdirXXXXXX'); + +my $tmpdir = mkdtemp($template); + +print "# MKDTEMP: Name is $tmpdir from template $template\n"; + +ok( (-d $tmpdir ) ); + +# Need to tidy up after myself +rmtree($tmpdir); + +# MKTEMP +# Just a filename, not opened + +$template = File::Spec->catfile(File::Spec->tmpdir, 'mytestXXXXXX'); + +my $tmpfile = mktemp($template); + +print "# MKTEMP: Tempfile is $template -> $tmpfile\n"; + +# Okay if template no longer has XXXXX in + + +ok( ($tmpfile !~ /XXXXX$/) ); diff --git a/contrib/perl5/t/lib/ftmp-posix.t b/contrib/perl5/t/lib/ftmp-posix.t new file mode 100755 index 0000000..79496d8 --- /dev/null +++ b/contrib/perl5/t/lib/ftmp-posix.t @@ -0,0 +1,81 @@ +#!/usr/bin/perl -w +# Test for File::Temp - POSIX functions + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Test; import Test; + plan(tests => 7); +} + +use strict; + +use File::Temp qw/ :POSIX unlink0 /; +ok(1); + +# TMPNAM - scalar + +print "# TMPNAM: in a scalar context: \n"; +my $tmpnam = tmpnam(); + +# simply check that the file does not exist +# Not a 100% water tight test though if another program +# has managed to create one in the meantime. +ok( !(-e $tmpnam )); + +print "# TMPNAM file name: $tmpnam\n"; + +# TMPNAM list context +# Not strict posix behaviour +(my $fh, $tmpnam) = tmpnam(); + +print "# TMPNAM: in list context: $fh $tmpnam\n"; + +# File is opened - make sure it exists +ok( (-e $tmpnam )); + +# Unlink it - a possible NFS issue again if TMPDIR is not a local disk +my $status = unlink0($fh, $tmpnam); +if ($status) { + ok( $status ); +} else { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); +} + +# TMPFILE + +$fh = tmpfile(); + +if (defined $fh) { + ok( $fh ); + print "# TMPFILE: tmpfile got FH $fh\n"; + + $fh->autoflush(1) if $] >= 5.006; + + # print something to it + my $original = "Hello a test\n"; + print "# TMPFILE: Wrote line: $original"; + print $fh $original + or die "Error printing to tempfile\n"; + + # rewind it + ok( seek($fh,0,0) ); + + # Read from it + my $line = <$fh>; + + print "# TMPFILE: Read line: $line"; + ok( $original, $line); + + close($fh); + +} else { + # Skip all the remaining tests + foreach (1..3) { + skip("Skip test failed probably due to \$TMPDIR being on NFS",1); + } +} + + + + diff --git a/contrib/perl5/t/lib/ftmp-security.t b/contrib/perl5/t/lib/ftmp-security.t new file mode 100755 index 0000000..96b2c42 --- /dev/null +++ b/contrib/perl5/t/lib/ftmp-security.t @@ -0,0 +1,140 @@ +#!/usr/bin/perl -w +# Test for File::Temp - Security levels + +# Some of the security checking will not work on all platforms +# Test a simple open in the cwd and tmpdir foreach of the +# security levels + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Test; import Test; + plan(tests => 13); +} + +use strict; +use File::Spec; + +# Set up END block - this needs to happen before we load +# File::Temp since this END block must be evaluated after the +# END block configured by File::Temp +my @files; # list of files to remove +END { foreach (@files) { ok( !(-e $_) )} } + +use File::Temp qw/ tempfile unlink0 /; +ok(1); + +# The high security tests must currently be skipped on some platforms +my $skipplat = ( ( + # No sticky bits. + $^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'dos' + ) ? 1 : 0 ); + +# Can not run high security tests in perls before 5.6.0 +my $skipperl = ($] < 5.006 ? 1 : 0 ); + +# Determine whether we need to skip things and why +my $skip = 0; +if ($skipplat) { + $skip = "Skip Not supported on this platform"; +} elsif ($skipperl) { + $skip = "Skip Perl version must be v5.6.0 for these tests"; + +} + +print "# We will be skipping some tests : $skip\n" if $skip; + +# start off with basic checking + +File::Temp->safe_level( File::Temp::STANDARD ); + +print "# Testing with STANDARD security...\n"; + +&test_security(0); + +# Try medium + +File::Temp->safe_level( File::Temp::MEDIUM ) + unless $skip; + +print "# Testing with MEDIUM security...\n"; + +# Now we need to start skipping tests +&test_security($skip); + +# Try HIGH + +File::Temp->safe_level( File::Temp::HIGH ) + unless $skip; + +print "# Testing with HIGH security...\n"; + +&test_security($skip); + +exit; + +# Subroutine to open two temporary files. +# one is opened in the current dir and the other in the temp dir + +sub test_security { + + # Read in the skip flag + my $skip = shift; + + # If we are skipping we need to simply fake the correct number + # of tests -- we dont use skip since the tempfile() commands will + # fail with MEDIUM/HIGH security before the skip() command would be run + if ($skip) { + + skip($skip,1); + skip($skip,1); + + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip,1); skip($skip,1) } 1; } || die; + + return; + } + + # Create the tempfile + my $template = "tmpXXXXX"; + my ($fh1, $fname1) = eval { tempfile ( $template, + DIR => File::Spec->tmpdir, + UNLINK => 1, + ); + }; + + if (defined $fname1) { + print "# fname1 = $fname1\n"; + ok( (-e $fname1) ); + push(@files, $fname1); # store for end block + } elsif (File::Temp->safe_level() != File::Temp::STANDARD) { + my $skip2 = "Skip system possibly insecure, see INSTALL, section 'make test'"; + skip($skip2, 1); + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip2,1); } 1; } || die; + } else { + ok(0); + } + + # Explicitly + if ( $< < File::Temp->top_system_uid() ){ + skip("Skip Test inappropriate for root", 1); + eval q{ END { skip($skip,1); } 1; } || die; + return; + } + my ($fh2, $fname2) = eval { tempfile ($template, UNLINK => 1 ); }; + if (defined $fname2) { + print "# fname2 = $fname2\n"; + ok( (-e $fname2) ); + push(@files, $fname2); # store for end block + close($fh2); + } elsif (File::Temp->safe_level() != File::Temp::STANDARD) { + my $skip2 = "Skip system possibly insecure, see INSTALL, section 'make test'"; + skip($skip2, 1); + # plus we need an end block so the tests come out in the right order + eval q{ END { skip($skip2,1); } 1; } || die; + } else { + ok(0); + } + +} diff --git a/contrib/perl5/t/lib/ftmp-tempfile.t b/contrib/perl5/t/lib/ftmp-tempfile.t new file mode 100755 index 0000000..ed59765 --- /dev/null +++ b/contrib/perl5/t/lib/ftmp-tempfile.t @@ -0,0 +1,145 @@ +#!/usr/local/bin/perl -w +# Test for File::Temp - tempfile function + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Test; import Test; + plan(tests => 20); +} + +use strict; +use File::Spec; + +# Will need to check that all files were unlinked correctly +# Set up an END block here to do it + +# Arrays containing list of dirs/files to test +my (@files, @dirs, @still_there); + +# And a test for files that should still be around +# These are tidied up +END { + foreach (@still_there) { + ok( -f $_ ); + ok( unlink( $_ ) ); + ok( !(-f $_) ); + } +} + +# Loop over an array hoping that the files dont exist +END { foreach (@files) { ok( !(-e $_) )} } + +# And a test for directories +END { foreach (@dirs) { ok( !(-d $_) )} } + +# Need to make sure that the END blocks are setup before +# the ones that File::Temp configures since END blocks are evaluated +# in revers order and we need to check the files *after* File::Temp +# removes them +use File::Temp qw/ tempfile tempdir/; + +# Now we start the tests properly +ok(1); + + +# Tempfile +# Open tempfile in some directory, unlink at end +my ($fh, $tempfile) = tempfile( + UNLINK => 1, + SUFFIX => '.txt', + ); + +ok( (-f $tempfile) ); +# Should still be around after closing +ok( close( $fh ) ); +ok( (-f $tempfile) ); +# Check again at exit +push(@files, $tempfile); + +# TEMPDIR test +# Create temp directory in current dir +my $template = 'tmpdirXXXXXX'; +print "# Template: $template\n"; +my $tempdir = tempdir( $template , + DIR => File::Spec->curdir, + CLEANUP => 1, + ); + +print "# TEMPDIR: $tempdir\n"; + +ok( (-d $tempdir) ); +push(@dirs, $tempdir); + +# Create file in the temp dir +($fh, $tempfile) = tempfile( + DIR => $tempdir, + UNLINK => 1, + SUFFIX => '.dat', + ); + +print "# TEMPFILE: Created $tempfile\n"; + +ok( (-f $tempfile)); +push(@files, $tempfile); + +# Test tempfile +# ..and again +($fh, $tempfile) = tempfile( + DIR => $tempdir, + ); + + +ok( (-f $tempfile )); +push(@files, $tempfile); + +print "# TEMPFILE: Created $tempfile\n"; + +# and another (with template) + +($fh, $tempfile) = tempfile( 'helloXXXXXXX', + DIR => $tempdir, + UNLINK => 1, + SUFFIX => '.dat', + ); + +print "# TEMPFILE: Created $tempfile\n"; + +ok( (-f $tempfile) ); +push(@files, $tempfile); + + +# Create a temporary file that should stay around after +# it has been closed +($fh, $tempfile) = tempfile( 'permXXXXXXX', UNLINK => 0 ); +print "# TEMPFILE: Created $tempfile\n"; +ok( -f $tempfile ); +ok( close( $fh ) ); +push( @still_there, $tempfile); # check at END + +# Would like to create a temp file and just retrieve the handle +# but the test is problematic since: +# - We dont know the filename so we cant check that it is tidied +# correctly +# - The unlink0 required on unix for tempfile creation will fail +# on NFS +# Try to do what we can. +# Tempfile croaks on error so we need an eval +$fh = eval { tempfile( 'ftmpXXXXX', DIR => File::Spec->tmpdir ) }; + +if ($fh) { + + # print something to it to make sure something is there + ok( print $fh "Test\n" ); + + # Close it - can not check it is gone since we dont know the name + ok( close($fh) ); + +} else { + skip "Skip Failed probably due to NFS", 1; + skip "Skip Failed probably due to NFS", 1; +} + +# Now END block will execute to test the removal of directories +print "# End of tests. Execute END blocks\n"; + diff --git a/contrib/perl5/t/lib/gol-oo.t b/contrib/perl5/t/lib/gol-oo.t new file mode 100755 index 0000000..98f3eaa --- /dev/null +++ b/contrib/perl5/t/lib/gol-oo.t @@ -0,0 +1,26 @@ +#!./perl -w + +BEGIN { + chdir('t') if -d 't'; + @INC = '../lib'; +} + +use Getopt::Long; +die("Getopt::Long version 2.24 required--this is only version ". + $Getopt::Long::VERSION) + unless $Getopt::Long::VERSION >= 2.24; +print "1..9\n"; + +@ARGV = qw(-Foo -baR --foo bar); +my $p = new Getopt::Long::Parser (config => ["no_ignore_case"]); +undef $opt_baR; +undef $opt_bar; +print "ok 1\n" if $p->getoptions ("foo", "Foo=s"); +print ((defined $opt_foo) ? "" : "not ", "ok 2\n"); +print (($opt_foo == 1) ? "" : "not ", "ok 3\n"); +print ((defined $opt_Foo) ? "" : "not ", "ok 4\n"); +print (($opt_Foo eq "-baR") ? "" : "not ", "ok 5\n"); +print ((@ARGV == 1) ? "" : "not ", "ok 6\n"); +print (($ARGV[0] eq "bar") ? "" : "not ", "ok 7\n"); +print (!(defined $opt_baR) ? "" : "not ", "ok 8\n"); +print (!(defined $opt_bar) ? "" : "not ", "ok 9\n"); diff --git a/contrib/perl5/t/lib/peek.t b/contrib/perl5/t/lib/peek.t new file mode 100755 index 0000000..fe9cb2c --- /dev/null +++ b/contrib/perl5/t/lib/peek.t @@ -0,0 +1,312 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bPeek\b/) { + print "1..0 # Skip: Devel::Peek was not built\n"; + exit 0; + } +} + +use Devel::Peek; + +print "1..17\n"; + +our $DEBUG = 0; +open(SAVERR, ">&STDERR") or die "Can't dup STDERR: $!"; + +sub do_test { + my $pattern = pop; + if (open(OUT,">peek$$")) { + open(STDERR, ">&OUT") or die "Can't dup OUT: $!"; + Dump($_[1]); + open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!"; + close(OUT); + if (open(IN, "peek$$")) { + local $/; + $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g; + print $pattern, "\n" if $DEBUG; + my $dump = <IN>; + print $dump, "\n" if $DEBUG; + print "[$dump] vs [$pattern]\nnot " unless $dump =~ /$pattern/ms; + print "ok $_[0]\n"; + close(IN); + } else { + die "$0: failed to open peek$$: !\n"; + } + } else { + die "$0: failed to create peek$$: $!\n"; + } +} + +our $a; +our $b; +my $c; +local $d = 0; + +do_test( 1, + $a = "foo", +'SV = PV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(POK,pPOK\\) + PV = $ADDR "foo"\\\0 + CUR = 3 + LEN = 4' + ); + +do_test( 2, + "bar", +'SV = PV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(.*POK,READONLY,pPOK\\) + PV = $ADDR "bar"\\\0 + CUR = 3 + LEN = 4'); + +do_test( 3, + $b = 123, +'SV = IV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(IOK,pIOK\\) + IV = 123'); + +do_test( 4, + 456, +'SV = IV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(.*IOK,READONLY,pIOK\\) + IV = 456'); + +do_test( 5, + $c = 456, +'SV = IV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(PADBUSY,PADMY,IOK,pIOK\\) + IV = 456'); + +do_test( 6, + $c + $d, +'SV = NV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(PADTMP,NOK,pNOK\\) + NV = 456'); + +($d = "789") += 0.1; + +do_test( 7, + $d, +'SV = PVNV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(NOK,pNOK\\) + IV = 0 + NV = 789\\.(?:1(?:000+\d+)?|0999+\d+) + PV = $ADDR "789"\\\0 + CUR = 3 + LEN = 4'); + +do_test( 8, + 0xabcd, +'SV = IV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(.*IOK,READONLY,pIOK,IsUV\\) + UV = 43981'); + +do_test( 9, + undef, +'SV = NULL\\(0x0\\) at $ADDR + REFCNT = 1 + FLAGS = \\(\\)'); + +do_test(10, + \$a, +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PV\\($ADDR\\) at $ADDR + REFCNT = 2 + FLAGS = \\(POK,pPOK\\) + PV = $ADDR "foo"\\\0 + CUR = 3 + LEN = 4'); + +do_test(11, + [$b,$c], +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVAV\\($ADDR\\) at $ADDR + REFCNT = 2 + FLAGS = \\(\\) + IV = 0 + NV = 0 + ARRAY = $ADDR + FILL = 1 + MAX = 1 + ARYLEN = 0x0 + FLAGS = \\(REAL\\) + Elt No. 0 + SV = IV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(IOK,pIOK\\) + IV = 123 + Elt No. 1 + SV = PVNV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(IOK,NOK,pIOK,pNOK\\) + IV = 456 + NV = 456 + PV = 0'); + +do_test(12, + {$b=>$c}, +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVHV\\($ADDR\\) at $ADDR + REFCNT = 2 + FLAGS = \\(SHAREKEYS\\) + IV = 1 + NV = 0 + ARRAY = $ADDR \\(0:7, 1:1\\) + hash quality = 150.0% + KEYS = 1 + FILL = 1 + MAX = 7 + RITER = -1 + EITER = 0x0 + Elt "123" HASH = $ADDR + SV = PVNV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(IOK,NOK,pIOK,pNOK\\) + IV = 456 + NV = 456 + PV = 0'); + +do_test(13, + sub(){@_}, +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVCV\\($ADDR\\) at $ADDR + REFCNT = 2 + FLAGS = \\(PADBUSY,PADMY,POK,pPOK,ANON\\) + IV = 0 + NV = 0 + PROTOTYPE = "" + COMP_STASH = $ADDR\\t"main" + START = $ADDR ===> \\d+ + ROOT = $ADDR + XSUB = 0x0 + XSUBANY = 0 + GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*" + FILE = ".*\\b(?i:peek\\.t)" + DEPTH = 0 +(?: MUTEXP = $ADDR + OWNER = $ADDR +)? FLAGS = 0x4 + PADLIST = $ADDR + OUTSIDE = $ADDR \\(MAIN\\)'); + +do_test(14, + \&do_test, +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVCV\\($ADDR\\) at $ADDR + REFCNT = (3|4) + FLAGS = \\(\\) + IV = 0 + NV = 0 + COMP_STASH = $ADDR\\t"main" + START = $ADDR ===> \\d+ + ROOT = $ADDR + XSUB = 0x0 + XSUBANY = 0 + GVGV::GV = $ADDR\\t"main" :: "do_test" + FILE = ".*\\b(?i:peek\\.t)" + DEPTH = 1 +(?: MUTEXP = $ADDR + OWNER = $ADDR +)? FLAGS = 0x0 + PADLIST = $ADDR + \\d+\\. $ADDR \\("\\$pattern" \\d+-\\d+\\) + \\d+\\. $ADDR \\(FAKE "\\$DEBUG" 0-\\d+\\) + \\d+\\. $ADDR \\("\\$dump" \\d+-\\d+\\) + OUTSIDE = $ADDR \\(MAIN\\)'); + +do_test(15, + qr(tic), +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVMG\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(OBJECT,RMG\\) + IV = 0 + NV = 0 + PV = 0 + MAGIC = $ADDR + MG_VIRTUAL = $ADDR + MG_TYPE = \'r\' + MG_OBJ = $ADDR + STASH = $ADDR\\t"Regexp"'); + +do_test(16, + (bless {}, "Tac"), +'SV = RV\\($ADDR\\) at $ADDR + REFCNT = 1 + FLAGS = \\(ROK\\) + RV = $ADDR + SV = PVHV\\($ADDR\\) at $ADDR + REFCNT = 2 + FLAGS = \\(OBJECT,SHAREKEYS\\) + IV = 0 + NV = 0 + STASH = $ADDR\\t"Tac" + ARRAY = 0x0 + KEYS = 0 + FILL = 0 + MAX = 7 + RITER = -1 + EITER = 0x0'); + +do_test(17, + *a, +'SV = PVGV\\($ADDR\\) at $ADDR + REFCNT = 5 + FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) + IV = 0 + NV = 0 + MAGIC = $ADDR + MG_VIRTUAL = &PL_vtbl_glob + MG_TYPE = \'\\*\' + MG_OBJ = $ADDR + NAME = "a" + NAMELEN = 1 + GvSTASH = $ADDR\\t"main" + GP = $ADDR + SV = $ADDR + REFCNT = 1 + IO = 0x0 + FORM = 0x0 + AV = 0x0 + HV = 0x0 + CV = 0x0 + CVGEN = 0x0 + GPFLAGS = 0x0 + LINE = \\d+ + FILE = ".*\\b(?i:peek\\.t)" + FLAGS = $ADDR + EGV = $ADDR\\t"a"'); + +END { + 1 while unlink("peek$$"); +} diff --git a/contrib/perl5/t/lib/selfloader.t b/contrib/perl5/t/lib/selfloader.t new file mode 100755 index 0000000..6b9c244 --- /dev/null +++ b/contrib/perl5/t/lib/selfloader.t @@ -0,0 +1,201 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + $dir = "self-$$"; + @INC = $dir; + push @INC, '../lib'; + + print "1..19\n"; + + # First we must set up some selfloader files + mkdir $dir, 0755 or die "Can't mkdir $dir: $!"; + + open(FOO, ">$dir/Foo.pm") or die; + print FOO <<'EOT'; +package Foo; +use SelfLoader; + +sub new { bless {}, shift } +sub foo; +sub bar; +sub bazmarkhianish; +sub a; +sub never; # declared but definition should never be read +1; +__DATA__ + +sub foo { shift; shift || "foo" }; + +sub bar { shift; shift || "bar" } + +sub bazmarkhianish { shift; shift || "baz" } + +package sheep; +sub bleat { shift; shift || "baa" } + +__END__ +sub never { die "D'oh" } +EOT + + close(FOO); + + open(BAR, ">$dir/Bar.pm") or die; + print BAR <<'EOT'; +package Bar; +use SelfLoader; + +@ISA = 'Baz'; + +sub new { bless {}, shift } +sub a; + +1; +__DATA__ + +sub a { 'a Bar'; } +sub b { 'b Bar' } + +__END__ DATA +sub never { die "D'oh" } +EOT + + close(BAR); +}; + + +package Baz; + +sub a { 'a Baz' } +sub b { 'b Baz' } +sub c { 'c Baz' } + + +package main; +use Foo; +use Bar; + +$foo = new Foo; + +print "not " unless $foo->foo eq 'foo'; # selfloaded first time +print "ok 1\n"; + +print "not " unless $foo->foo eq 'foo'; # regular call +print "ok 2\n"; + +# Try an undefined method +eval { + $foo->will_fail; +}; +if ($@ =~ /^Undefined subroutine/) { + print "ok 3\n"; +} else { + print "not ok 3 $@\n"; +} + +# Used to be trouble with this +eval { + my $foo = new Foo; + die "oops"; +}; +if ($@ =~ /oops/) { + print "ok 4\n"; +} else { + print "not ok 4 $@\n"; +} + +# Pass regular expression variable to autoloaded function. This used +# to go wrong in AutoLoader because it used regular expressions to generate +# autoloaded filename. +"foo" =~ /(\w+)/; +print "not " unless $1 eq 'foo'; +print "ok 5\n"; + +print "not " unless $foo->bar($1) eq 'foo'; +print "ok 6\n"; + +print "not " unless $foo->bar($1) eq 'foo'; +print "ok 7\n"; + +print "not " unless $foo->bazmarkhianish($1) eq 'foo'; +print "ok 8\n"; + +print "not " unless $foo->bazmarkhianish($1) eq 'foo'; +print "ok 9\n"; + +# Check nested packages inside __DATA__ +print "not " unless sheep::bleat() eq 'baa'; +print "ok 10\n"; + +# Now check inheritance: + +$bar = new Bar; + +# Before anything is SelfLoaded there is no declaration of Foo::b so we should +# get Baz::b +print "not " unless $bar->b() eq 'b Baz'; +print "ok 11\n"; + +# There is no Bar::c so we should get Baz::c +print "not " unless $bar->c() eq 'c Baz'; +print "ok 12\n"; + +# This selfloads Bar::a because it is stubbed. It also stubs Bar::b as a side +# effect +print "not " unless $bar->a() eq 'a Bar'; +print "ok 13\n"; + +print "not " unless $bar->b() eq 'b Bar'; +print "ok 14\n"; + +print "not " unless $bar->c() eq 'c Baz'; +print "ok 15\n"; + + + +# Check that __END__ is honoured +# Try an subroutine that should never be noticed by selfloader +eval { + $foo->never; +}; +if ($@ =~ /^Undefined subroutine/) { + print "ok 16\n"; +} else { + print "not ok 16 $@\n"; +} + +# Try to read from the data file handle +my $foodata = <Foo::DATA>; +close Foo::DATA; +if (defined $foodata) { + print "not ok 17 # $foodata\n"; +} else { + print "ok 17\n"; +} + +# Check that __END__ DATA is honoured +# Try an subroutine that should never be noticed by selfloader +eval { + $bar->never; +}; +if ($@ =~ /^Undefined subroutine/) { + print "ok 18\n"; +} else { + print "not ok 18 $@\n"; +} + +# Try to read from the data file handle +my $bardata = <Bar::DATA>; +close Bar::DATA; +if ($bardata ne "sub never { die \"D'oh\" }\n") { + print "not ok 19 # $bardata\n"; +} else { + print "ok 19\n"; +} + +# cleanup +END { +return unless $dir && -d $dir; +unlink "$dir/Foo.pm", "$dir/Bar.pm"; +rmdir "$dir"; +} diff --git a/contrib/perl5/t/lib/syslog.t b/contrib/perl5/t/lib/syslog.t new file mode 100755 index 0000000..cd2fad7 --- /dev/null +++ b/contrib/perl5/t/lib/syslog.t @@ -0,0 +1,59 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bSyslog\b/) { + print "1..0 # Skip: Sys::Syslog was not built\n"; + exit 0; + } + + require Socket; + + # This code inspired by Sys::Syslog::connect(): + require Sys::Hostname; + my ($host_uniq) = Sys::Hostname::hostname(); + my ($host) = $host_uniq =~ /([A-Za-z0-9_.-]+)/; + + if (! defined Socket::inet_aton($host)) { + print "1..0 # Skip: Can't lookup $host\n"; + exit 0; + } +} + +BEGIN { + eval {require Sys::Syslog} or do { + if ($@ =~ /Your vendor has not/) { + print "1..0 # Skipped: missing macros\n"; + exit 0; + } + } +} + +use Sys::Syslog qw(:DEFAULT setlogsock); + +print "1..6\n"; + +if (Sys::Syslog::_PATH_LOG()) { + if (-e Sys::Syslog::_PATH_LOG()) { + print defined(eval { setlogsock('unix') }) ? "ok 1\n" : "not ok 1\n"; + print defined(eval { openlog('perl', 'ndelay', 'local0') }) ? "ok 2\n" : "not ok 2\n"; + print defined(eval { syslog('info', 'test') }) ? "ok 3\n" : "not ok 3\n"; + } + else { + for (1..3) { + print + "ok $_ # skipping, file ", + Sys::Syslog::_PATH_LOG(), + " does not exist\n"; + } + } +} +else { + for (1..3) { print "ok $_ # skipping, _PATH_LOG unavailable\n" } +} + +print defined(eval { setlogsock('inet') }) ? "ok 4\n" : "not ok 4\n"; +print defined(eval { openlog('perl', 'ndelay', 'local0') }) ? "ok 5\n" : "not ok 5\n"; +print defined(eval { syslog('info', 'test') }) ? "ok 6\n" : "not ok 6\n"; diff --git a/contrib/perl5/t/lib/tie-refhash.t b/contrib/perl5/t/lib/tie-refhash.t new file mode 100755 index 0000000..d80b2e1 --- /dev/null +++ b/contrib/perl5/t/lib/tie-refhash.t @@ -0,0 +1,305 @@ +#!/usr/bin/perl -w +# +# Basic test suite for Tie::RefHash and Tie::RefHash::Nestable. +# +# The testing is in two parts: first, run lots of tests on both a tied +# hash and an ordinary un-tied hash, and check they give the same +# answer. Then there are tests for those cases where the tied hashes +# should behave differently to normal hashes, that is, when using +# references as keys. +# + +BEGIN { + chdir 't' if -d 't'; + @INC = '.'; + push @INC, '../lib'; +} + +use strict; +use Tie::RefHash; +use Data::Dumper; +my $numtests = 34; +my $currtest = 1; +print "1..$numtests\n"; + +my $ref = []; my $ref1 = []; + +# Test standard hash functionality, by performing the same operations +# on a tied hash and on a normal hash, and checking that the results +# are the same. This does of course assume that Perl hashes are not +# buggy :-) +# +my @tests = standard_hash_tests(); + +my @ordinary_results = runtests(\@tests, undef); +foreach my $class ('Tie::RefHash', 'Tie::RefHash::Nestable') { + my @tied_results = runtests(\@tests, $class); + my $all_ok = 1; + + die if @ordinary_results != @tied_results; + foreach my $i (0 .. $#ordinary_results) { + my ($or, $ow, $oe) = @{$ordinary_results[$i]}; + my ($tr, $tw, $te) = @{$tied_results[$i]}; + + my $ok = 1; + local $^W = 0; + $ok = 0 if (defined($or) != defined($tr)) or ($or ne $tr); + $ok = 0 if (defined($ow) != defined($tw)) or ($ow ne $tw); + $ok = 0 if (defined($oe) != defined($te)) or ($oe ne $te); + + if (not $ok) { + print STDERR + "failed for $class: $tests[$i]\n", + "ordinary hash gave:\n", + defined $or ? "\tresult: $or\n" : "\tundef result\n", + defined $ow ? "\twarning: $ow\n" : "\tno warning\n", + defined $oe ? "\texception: $oe\n" : "\tno exception\n", + "tied $class hash gave:\n", + defined $tr ? "\tresult: $tr\n" : "\tundef result\n", + defined $tw ? "\twarning: $tw\n" : "\tno warning\n", + defined $te ? "\texception: $te\n" : "\tno exception\n", + "\n"; + $all_ok = 0; + } + } + test($all_ok); +} + +# Now test Tie::RefHash's special powers +my (%h, $h); +$h = eval { tie %h, 'Tie::RefHash' }; +warn $@ if $@; +test(not $@); +test(ref($h) eq 'Tie::RefHash'); +test(defined(tied(%h)) and tied(%h) =~ /^Tie::RefHash/); +$h{$ref} = 'cholet'; +test($h{$ref} eq 'cholet'); +test(exists $h{$ref}); +test((keys %h) == 1); +test(ref((keys %h)[0]) eq 'ARRAY'); +test((keys %h)[0] eq $ref); +test((values %h) == 1); +test((values %h)[0] eq 'cholet'); +my $count = 0; +while (my ($k, $v) = each %h) { + if ($count++ == 0) { + test(ref($k) eq 'ARRAY'); + test($k eq $ref); + } +} +test($count == 1); +delete $h{$ref}; +test(not defined $h{$ref}); +test(not exists($h{$ref})); +test((keys %h) == 0); +test((values %h) == 0); +undef $h; +untie %h; + +# And now Tie::RefHash::Nestable's differences from Tie::RefHash. +$h = eval { tie %h, 'Tie::RefHash::Nestable' }; +warn $@ if $@; +test(not $@); +test(ref($h) eq 'Tie::RefHash::Nestable'); +test(defined(tied(%h)) and tied(%h) =~ /^Tie::RefHash::Nestable/); +$h{$ref}->{$ref1} = 'bungo'; +test($h{$ref}->{$ref1} eq 'bungo'); + +# Test that the nested hash is also tied (for current implementation) +test(defined(tied(%{$h{$ref}})) + and tied(%{$h{$ref}}) =~ /^Tie::RefHash::Nestable=/ ); + +test((keys %h) == 1); +test((keys %h)[0] eq $ref); +test((keys %{$h{$ref}}) == 1); +test((keys %{$h{$ref}})[0] eq $ref1); + + +die "expected to run $numtests tests, but ran ", $currtest - 1 + if $currtest - 1 != $numtests; + +@tests = (); +undef $ref; +undef $ref1; + +exit(); + + +# Print 'ok X' if true, 'not ok X' if false +# Uses global $currtest. +# +sub test { + my $t = shift; + print 'not ' if not $t; + print 'ok ', $currtest++, "\n"; +} + + +# Wrapper for Data::Dumper to 'dump' a scalar as an EXPR string. +sub dumped { + my $s = shift; + my $d = Dumper($s); + $d =~ s/^\$VAR1 =\s*//; + $d =~ s/;$//; + chomp $d; + return $d; +} + +# Crudely dump a hash into a canonical string representation (because +# hash keys can appear in any order, Data::Dumper may give different +# strings for the same hash). +# +sub dumph { + my $h = shift; + my $r = ''; + foreach (sort keys %$h) { + $r = dumped($_) . ' => ' . dumped($h->{$_}) . "\n"; + } + return $r; +} + +# Run the tests and give results. +# +# Parameters: reference to list of tests to run +# name of class to use for tied hash, or undef if not tied +# +# Returns: list of [R, W, E] tuples, one for each test. +# R is the return value from running the test, W any warnings it gave, +# and E any exception raised with 'die'. E and W will be tidied up a +# little to remove irrelevant details like line numbers :-) +# +# Will also run a few of its own 'ok N' tests. +# +sub runtests { + my ($tests, $class) = @_; + my @r; + + my (%h, $h); + if (defined $class) { + $h = eval { tie %h, $class }; + warn $@ if $@; + test(not $@); + test(ref($h) eq $class); + test(defined(tied(%h)) and tied(%h) =~ /^\Q$class\E/); + } + + foreach (@$tests) { + my ($result, $warning, $exception); + local $SIG{__WARN__} = sub { $warning .= $_[0] }; + $result = scalar(eval $_); + if ($@) + { + die "$@:$_" unless defined $class; + $exception = $@; + } + + foreach ($warning, $exception) { + next if not defined; + s/ at .+ line \d+\.$//mg; + s/ at .+ line \d+, at .*//mg; + s/ at .+ line \d+, near .*//mg; + } + + my (@warnings, %seen); + foreach (split /\n/, $warning) { + push @warnings, $_ unless $seen{$_}++; + } + $warning = join("\n", @warnings); + + push @r, [ $result, $warning, $exception ]; + } + + return @r; +} + + +# Things that should work just the same for an ordinary hash and a +# Tie::RefHash. +# +# Each test is a code string to be eval'd, it should do something with +# %h and give a scalar return value. The global $ref and $ref1 may +# also be used. +# +# One thing we don't test is that the ordering from 'keys', 'values' +# and 'each' is the same. You can't reasonably expect that. +# +sub standard_hash_tests { + my @r; + + # Library of standard tests on keys, values and each + my $STD_TESTS = <<'END' + join $;, sort keys %h; + join $;, sort values %h; + { my ($v, %tmp); $tmp{$v}++ while (defined($v = each %h)); dumph(\%tmp) } + { my ($k, $v, %tmp); $tmp{"$k$;$v"}++ while (($k, $v) = each %h); dumph(\%tmp) } +END + ; + + # Tests on the existence of the element 'foo' + my $FOO_TESTS = <<'END' + defined $h{foo}; + exists $h{foo}; + $h{foo}; +END + ; + + # Test storing and deleting 'foo' + push @r, split /\n/, <<"END" + $STD_TESTS; + $FOO_TESTS; + \$h{foo} = undef; + $STD_TESTS; + $FOO_TESTS; + \$h{foo} = 'hello'; + $STD_TESTS; + $FOO_TESTS; + delete \$h{foo}; + $STD_TESTS; + $FOO_TESTS; +END + ; + + # Test storing and removing under ordinary keys + my @things = ('boink', 0, 1, '', undef); + foreach my $key (map { dumped($_) } @things) { + foreach my $value ((map { dumped($_) } @things), '$ref') { + push @r, split /\n/, <<"END" + \$h{$key} = $value; + $STD_TESTS; + defined \$h{$key}; + exists \$h{$key}; + \$h{$key}; + delete \$h{$key}; + $STD_TESTS; + defined \$h{$key}; + exists \$h{$key}; + \$h{$key}; +END + ; + } + } + + # Test hash slices + my @slicetests; + @slicetests = split /\n/, <<'END' + @h{'b'} = (); + @h{'c'} = ('d'); + @h{'e'} = ('f', 'g'); + @h{'h', 'i'} = (); + @h{'j', 'k'} = ('l'); + @h{'m', 'n'} = ('o', 'p'); + @h{'q', 'r'} = ('s', 't', 'u'); +END + ; + my @aaa = @slicetests; + foreach (@slicetests) { + push @r, $_; + push @r, split(/\n/, $STD_TESTS); + } + + # Test CLEAR + push @r, '%h = ();', split(/\n/, $STD_TESTS); + + return @r; +} + diff --git a/contrib/perl5/t/lib/tie-splice.t b/contrib/perl5/t/lib/tie-splice.t new file mode 100755 index 0000000..d7ea6cc --- /dev/null +++ b/contrib/perl5/t/lib/tie-splice.t @@ -0,0 +1,17 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = '.'; + push @INC, '../lib'; +} + +# bug id 20001020.002 +# -dlc 20001021 + +use Tie::Array; +tie @a,Tie::StdArray; +undef *Tie::StdArray::SPLICE; +require "op/splice.t" + +# Pre-fix, this failed tests 6-9 diff --git a/contrib/perl5/t/lib/tie-substrhash.t b/contrib/perl5/t/lib/tie-substrhash.t new file mode 100755 index 0000000..8256db7 --- /dev/null +++ b/contrib/perl5/t/lib/tie-substrhash.t @@ -0,0 +1,111 @@ +#!/usr/bin/perl -w +# + +BEGIN { + chdir 't' if -d 't'; + @INC = '.'; + push @INC, '../lib'; +} + +print "1..20\n"; + +use strict; + +require Tie::SubstrHash; + +my %a; + +tie %a, 'Tie::SubstrHash', 3, 3, 3; + +$a{abc} = 123; +$a{bcd} = 234; + +print "not " unless $a{abc} == 123; +print "ok 1\n"; + +print "not " unless keys %a == 2; +print "ok 2\n"; + +delete $a{abc}; + +print "not " unless $a{bcd} == 234; +print "ok 3\n"; + +print "not " unless (values %a)[0] == 234; +print "ok 4\n"; + +eval { $a{abcd} = 123 }; +print "not " unless $@ =~ /Key "abcd" is not 3 characters long/; +print "ok 5\n"; + +eval { $a{abc} = 1234 }; +print "not " unless $@ =~ /Value "1234" is not 3 characters long/; +print "ok 6\n"; + +eval { $a = $a{abcd}; $a++ }; +print "not " unless $@ =~ /Key "abcd" is not 3 characters long/; +print "ok 7\n"; + +@a{qw(abc cde)} = qw(123 345); + +print "not " unless $a{cde} == 345; +print "ok 8\n"; + +eval { $a{def} = 456 }; +print "not " unless $@ =~ /Table is full \(3 elements\)/; +print "ok 9\n"; + +%a = (); + +print "not " unless keys %a == 0; +print "ok 10\n"; + +# Tests 11..16 by Linc Madison. + +my $hashsize = 119; # arbitrary values from my data +my %test; +tie %test, "Tie::SubstrHash", 13, 86, $hashsize; + +for (my $i = 1; $i <= $hashsize; $i++) { + my $key1 = $i + 100_000; # fix to uniform 6-digit numbers + my $key2 = "abcdefg$key1"; + $test{$key2} = ("abcdefgh" x 10) . "$key1"; +} + +for (my $i = 1; $i <= $hashsize; $i++) { + my $key1 = $i + 100_000; + my $key2 = "abcdefg$key1"; + unless ($test{$key2}) { + print "not "; + last; + } +} +print "ok 11\n"; + +print "not " unless Tie::SubstrHash::findgteprime(1) == 2; +print "ok 12\n"; + +print "not " unless Tie::SubstrHash::findgteprime(2) == 2; +print "ok 13\n"; + +print "not " unless Tie::SubstrHash::findgteprime(5.5) == 7; +print "ok 14\n"; + +print "not " unless Tie::SubstrHash::findgteprime(13) == 13; +print "ok 15\n"; + +print "not " unless Tie::SubstrHash::findgteprime(13.000001) == 17; +print "ok 16\n"; + +print "not " unless Tie::SubstrHash::findgteprime(114) == 127; +print "ok 17\n"; + +print "not " unless Tie::SubstrHash::findgteprime(1000) == 1009; +print "ok 18\n"; + +print "not " unless Tie::SubstrHash::findgteprime(1024) == 1031; +print "ok 19\n"; + +print "not " unless Tie::SubstrHash::findgteprime(10000) == 10007; +print "ok 20\n"; + |