Upgrade to Test::Simple 0.60
Rafael Garcia-Suarez [Thu, 5 May 2005 14:41:55 +0000 (14:41 +0000)]
p4raw-id: //depot/perl@24397

14 files changed:
MANIFEST
lib/Test/Builder.pm
lib/Test/More.pm
lib/Test/Simple.pm
lib/Test/Simple/Changes
lib/Test/Simple/t/00signature.t
lib/Test/Simple/t/circular_data.t
lib/Test/Simple/t/exit.t
lib/Test/Simple/t/fork.t
lib/Test/Simple/t/has_plan.t
lib/Test/Simple/t/has_plan2.t
lib/Test/Simple/t/is_deeply.t [deleted file]
lib/Test/Simple/t/is_fh.t
lib/Test/Simple/t/require_ok.t

index 23b68c7..600775e 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1857,6 +1857,7 @@ lib/Test/Simple/t/bad_plan.t      Test::Builder plan() test
 lib/Test/Simple/t/buffer.t     Test::Builder buffering test
 lib/Test/Simple/t/Builder.t    Test::Builder tests
 lib/Test/Simple/t/circular_data.t      Test::Simple test
+lib/Test/Simple/t/create.t     Test::Simple test
 lib/Test/Simple/t/curr_test.t  Test::Builder->curr_test tests
 lib/Test/Simple/t/details.t    Test::Builder tests
 lib/Test/Simple/t/diag.t       Test::More diag() test
@@ -1874,7 +1875,7 @@ lib/Test/Simple/t/harness_active.t        Test::Simple test
 lib/Test/Simple/t/has_plan2.t  Test::More->plan tests
 lib/Test/Simple/t/has_plan.t   Test::Builder->plan tests
 lib/Test/Simple/t/import.t     Test::More test, importing functions
-lib/Test/Simple/t/is_deeply.t  Test::More test, is_deeply()
+lib/Test/Simple/t/is_deeply_fail.t     Test::More test, is_deeply()
 lib/Test/Simple/t/is_fh.t      Test::Builder test, _is_fh()
 lib/Test/Simple/t/maybe_regex.t        Test::Builder->maybe_regex() tests
 lib/Test/Simple/t/missing.t    Test::Simple test, missing tests
@@ -2647,6 +2648,7 @@ t/lib/strict/vars         Tests of "use strict 'vars'" for strict.t
 t/lib/Test/Simple/Catch.pm     Utility module for testing Test::Simple
 t/lib/Test/Simple/sample_tests/death_in_eval.plx       for exit.t
 t/lib/Test/Simple/sample_tests/death.plx               for exit.t
+t/lib/Test/Simple/sample_tests/exit.plx                        for exit.t
 t/lib/Test/Simple/sample_tests/extras.plx              for exit.t
 t/lib/Test/Simple/sample_tests/five_fail.plx           for exit.t
 t/lib/Test/Simple/sample_tests/last_minute_death.plx   for exit.t
index 9f6a3a4..859915b 100644 (file)
@@ -8,7 +8,7 @@ $^C ||= 0;
 
 use strict;
 use vars qw($VERSION);
-$VERSION = '0.22';
+$VERSION = '0.30';
 $VERSION = eval $VERSION;    # make the alpha version come out as a number
 
 # Make Test::Builder thread-safe for ithreads.
@@ -115,19 +115,48 @@ work together>.
 Returns a Test::Builder object representing the current state of the
 test.
 
-Since you only run one test per program, there is B<one and only one>
+Since you only run one test per program C<new> always returns the same
 Test::Builder object.  No matter how many times you call new(), you're
-getting the same object.  (This is called a singleton).
+getting the same object.  This is called a singleton.  This is done so that
+multiple modules share such global information as the test counter and
+where test output is going.
+
+If you want a completely new Test::Builder object different from the
+singleton, use C<create>.
 
 =cut
 
 my $Test = Test::Builder->new;
 sub new {
     my($class) = shift;
-    $Test ||= bless ['Move along, nothing to see here'], $class;
+    $Test ||= $class->create;
     return $Test;
 }
 
+
+=item B<create>
+
+  my $Test = Test::Builder->create;
+
+Ok, so there can be more than one Test::Builder object and this is how
+you get it.  You might use this instead of C<new()> if you're testing
+a Test::Builder based module, but otherwise you probably want C<new>.
+
+B<NOTE>: the implementation is not complete.  C<level>, for example, is
+still shared amongst B<all> Test::Builder objects, even ones created using
+this method.  Also, the method name may change in the future.
+
+=cut
+
+sub create {
+    my $class = shift;
+
+    my $self = bless {}, $class;
+    $self->reset;
+
+    return $self;
+}
+
 =item B<reset>
 
   $Test->reset;
@@ -138,44 +167,33 @@ test might be run multiple times in the same process.
 
 =cut
 
-my $Test_Died;
-my $Have_Plan;
-my $No_Plan;
-my $Curr_Test;     share($Curr_Test);
 use vars qw($Level);
-my $Original_Pid;
-my @Test_Results;  share(@Test_Results);
-
-my $Exported_To;
-my $Expected_Tests;
-
-my $Skip_All;
-
-my $Use_Nums;
-
-my($No_Header, $No_Ending);
-
-$Test->reset;
 
 sub reset {
     my ($self) = @_;
 
-    $Test_Died = 0;
-    $Have_Plan = 0;
-    $No_Plan   = 0;
-    $Curr_Test = 0;
-    $Level     = 1;
-    $Original_Pid = $$;
-    @Test_Results = ();
+    # We leave this a global because it has to be localized and localizing
+    # hash keys is just asking for pain.  Also, it was documented.
+    $Level = 1;
+
+    $self->{Test_Died}    = 0;
+    $self->{Have_Plan}    = 0;
+    $self->{No_Plan}      = 0;
+    $self->{Original_Pid} = $$;
 
-    $Exported_To    = undef;
-    $Expected_Tests = 0;
+    share($self->{Curr_Test});
+    $self->{Curr_Test}    = 0;
+    $self->{Test_Results} = &share([]);
 
-    $Skip_All = 0;
+    $self->{Exported_To}    = undef;
+    $self->{Expected_Tests} = 0;
 
-    $Use_Nums = 1;
+    $self->{Skip_All}   = 0;
 
-    ($No_Header, $No_Ending) = (0,0);
+    $self->{Use_Nums}   = 1;
+
+    $self->{No_Header}  = 0;
+    $self->{No_Ending}  = 0;
 
     $self->_dup_stdhandles unless $^C;
 
@@ -205,9 +223,9 @@ sub exported_to {
     my($self, $pack) = @_;
 
     if( defined $pack ) {
-        $Exported_To = $pack;
+        $self->{Exported_To} = $pack;
     }
-    return $Exported_To;
+    return $self->{Exported_To};
 }
 
 =item B<plan>
@@ -228,7 +246,7 @@ sub plan {
 
     return unless $cmd;
 
-    if( $Have_Plan ) {
+    if( $self->{Have_Plan} ) {
         die sprintf "You tried to plan twice!  Second plan at %s line %d\n",
           ($self->caller)[1,2];
     }
@@ -278,12 +296,12 @@ sub expected_tests {
         die "Number of tests must be a postive integer.  You gave it '$max'.\n"
           unless $max =~ /^\+?\d+$/ and $max > 0;
 
-        $Expected_Tests = $max;
-        $Have_Plan      = 1;
+        $self->{Expected_Tests} = $max;
+        $self->{Have_Plan}      = 1;
 
         $self->_print("1..$max\n") unless $self->no_header;
     }
-    return $Expected_Tests;
+    return $self->{Expected_Tests};
 }
 
 
@@ -296,22 +314,26 @@ Declares that this test will run an indeterminate # of tests.
 =cut
 
 sub no_plan {
-    $No_Plan    = 1;
-    $Have_Plan  = 1;
+    my $self = shift;
+
+    $self->{No_Plan}   = 1;
+    $self->{Have_Plan} = 1;
 }
 
 =item B<has_plan>
 
   $plan = $Test->has_plan
-  
+
 Find out whether a plan has been defined. $plan is either C<undef> (no plan has been set), C<no_plan> (indeterminate # of tests) or an integer (the number of expected tests).
 
 =cut
 
 sub has_plan {
-       return($Expected_Tests) if $Expected_Tests;
-       return('no_plan') if $No_Plan;
-       return(undef);
+    my $self = shift;
+
+    return($self->{Expected_Tests}) if $self->{Expected_Tests};
+    return('no_plan') if $self->{No_Plan};
+    return(undef);
 };
 
 
@@ -331,7 +353,7 @@ sub skip_all {
     $out .= " # Skip $reason" if $reason;
     $out .= "\n";
 
-    $Skip_All = 1;
+    $self->{Skip_All} = 1;
 
     $self->_print($out) unless $self->no_header;
     exit(0);
@@ -364,13 +386,13 @@ sub ok {
     # store, so we turn it into a boolean.
     $test = $test ? 1 : 0;
 
-    unless( $Have_Plan ) {
+    unless( $self->{Have_Plan} ) {
         require Carp;
         Carp::croak("You tried to run a test without a plan!  Gotta have a plan.");
     }
 
-    lock $Curr_Test;
-    $Curr_Test++;
+    lock $self->{Curr_Test};
+    $self->{Curr_Test}++;
 
     # In case $name is a string overloaded object, force it to stringify.
     $self->_unoverload(\$name);
@@ -397,7 +419,7 @@ ERR
     }
 
     $out .= "ok";
-    $out .= " $Curr_Test" if $self->use_numbers;
+    $out .= " $self->{Curr_Test}" if $self->use_numbers;
 
     if( defined $name ) {
         $name =~ s|#|\\#|g;     # # in a name can confuse Test::Harness.
@@ -418,7 +440,7 @@ ERR
         $result->{type}   = '';
     }
 
-    $Test_Results[$Curr_Test-1] = $result;
+    $self->{Test_Results}[$self->{Curr_Test}-1] = $result;
     $out .= "\n";
 
     $self->_print($out);
@@ -771,15 +793,15 @@ sub skip {
     $why ||= '';
     $self->_unoverload(\$why);
 
-    unless( $Have_Plan ) {
+    unless( $self->{Have_Plan} ) {
         require Carp;
         Carp::croak("You tried to run tests without a plan!  Gotta have a plan.");
     }
 
-    lock($Curr_Test);
-    $Curr_Test++;
+    lock($self->{Curr_Test});
+    $self->{Curr_Test}++;
 
-    $Test_Results[$Curr_Test-1] = &share({
+    $self->{Test_Results}[$self->{Curr_Test}-1] = &share({
         'ok'      => 1,
         actual_ok => 1,
         name      => '',
@@ -788,12 +810,12 @@ sub skip {
     });
 
     my $out = "ok";
-    $out   .= " $Curr_Test" if $self->use_numbers;
+    $out   .= " $self->{Curr_Test}" if $self->use_numbers;
     $out   .= " # skip";
     $out   .= " $why"       if length $why;
     $out   .= "\n";
 
-    $Test->_print($out);
+    $self->_print($out);
 
     return 1;
 }
@@ -815,15 +837,15 @@ sub todo_skip {
     my($self, $why) = @_;
     $why ||= '';
 
-    unless( $Have_Plan ) {
+    unless( $self->{Have_Plan} ) {
         require Carp;
         Carp::croak("You tried to run tests without a plan!  Gotta have a plan.");
     }
 
-    lock($Curr_Test);
-    $Curr_Test++;
+    lock($self->{Curr_Test});
+    $self->{Curr_Test}++;
 
-    $Test_Results[$Curr_Test-1] = &share({
+    $self->{Test_Results}[$self->{Curr_Test}-1] = &share({
         'ok'      => 1,
         actual_ok => 0,
         name      => '',
@@ -832,10 +854,10 @@ sub todo_skip {
     });
 
     my $out = "not ok";
-    $out   .= " $Curr_Test" if $self->use_numbers;
+    $out   .= " $self->{Curr_Test}" if $self->use_numbers;
     $out   .= " # TODO & SKIP $why\n";
 
-    $Test->_print($out);
+    $self->_print($out);
 
     return 1;
 }
@@ -921,9 +943,9 @@ sub use_numbers {
     my($self, $use_nums) = @_;
 
     if( defined $use_nums ) {
-        $Use_Nums = $use_nums;
+        $self->{Use_Nums} = $use_nums;
     }
-    return $Use_Nums;
+    return $self->{Use_Nums};
 }
 
 =item B<no_header>
@@ -947,18 +969,18 @@ sub no_header {
     my($self, $no_header) = @_;
 
     if( defined $no_header ) {
-        $No_Header = $no_header;
+        $self->{No_Header} = $no_header;
     }
-    return $No_Header;
+    return $self->{No_Header};
 }
 
 sub no_ending {
     my($self, $no_ending) = @_;
 
     if( defined $no_ending ) {
-        $No_Ending = $no_ending;
+        $self->{No_Ending} = $no_ending;
     }
-    return $No_Ending;
+    return $self->{No_Ending};
 }
 
 
@@ -1102,32 +1124,31 @@ Defaults to STDOUT.
 
 =cut
 
-my($Out_FH, $Fail_FH, $Todo_FH);
 sub output {
     my($self, $fh) = @_;
 
     if( defined $fh ) {
-        $Out_FH = _new_fh($fh);
+        $self->{Out_FH} = _new_fh($fh);
     }
-    return $Out_FH;
+    return $self->{Out_FH};
 }
 
 sub failure_output {
     my($self, $fh) = @_;
 
     if( defined $fh ) {
-        $Fail_FH = _new_fh($fh);
+        $self->{Fail_FH} = _new_fh($fh);
     }
-    return $Fail_FH;
+    return $self->{Fail_FH};
 }
 
 sub todo_output {
     my($self, $fh) = @_;
 
     if( defined $fh ) {
-        $Todo_FH = _new_fh($fh);
+        $self->{Todo_FH} = _new_fh($fh);
     }
-    return $Todo_FH;
+    return $self->{Todo_FH};
 }
 
 
@@ -1142,6 +1163,7 @@ sub _new_fh {
         $fh = do { local *FH };
         open $fh, ">$file_or_fh" or 
             die "Can't open test output log $file_or_fh: $!";
+       _autoflush($fh);
     }
 
     return $fh;
@@ -1169,11 +1191,10 @@ sub _autoflush {
 }
 
 
-my $Opened_Testhandles = 0;
 sub _dup_stdhandles {
     my $self = shift;
 
-    $self->_open_testhandles unless $Opened_Testhandles;
+    $self->_open_testhandles;
 
     # Set everything to unbuffered else plain prints to STDOUT will
     # come out in the wrong order from our own prints.
@@ -1182,12 +1203,15 @@ sub _dup_stdhandles {
     _autoflush(\*TESTERR);
     _autoflush(\*STDERR);
 
-    $Test->output(\*TESTOUT);
-    $Test->failure_output(\*TESTERR);
-    $Test->todo_output(\*TESTOUT);
+    $self->output(\*TESTOUT);
+    $self->failure_output(\*TESTERR);
+    $self->todo_output(\*TESTOUT);
 }
 
+
+my $Opened_Testhandles = 0;
 sub _open_testhandles {
+    return if $Opened_Testhandles;
     # We dup STDOUT and STDERR so people can change them in their
     # test suites while still getting normal test output.
     open(TESTOUT, ">&STDOUT") or die "Can't dup STDOUT:  $!";
@@ -1220,20 +1244,21 @@ can erase history if you really want to.
 sub current_test {
     my($self, $num) = @_;
 
-    lock($Curr_Test);
+    lock($self->{Curr_Test});
     if( defined $num ) {
-        unless( $Have_Plan ) {
+        unless( $self->{Have_Plan} ) {
             require Carp;
             Carp::croak("Can't change the current test number without a plan!");
         }
 
-        $Curr_Test = $num;
+        $self->{Curr_Test} = $num;
 
         # If the test counter is being pushed forward fill in the details.
-        if( $num > @Test_Results ) {
-            my $start = @Test_Results ? $#Test_Results + 1 : 0;
+        my $test_results = $self->{Test_Results};
+        if( $num > @$test_results ) {
+            my $start = @$test_results ? @$test_results : 0;
             for ($start..$num-1) {
-                $Test_Results[$_] = &share({
+                $test_results->[$_] = &share({
                     'ok'      => 1, 
                     actual_ok => undef, 
                     reason    => 'incrementing test number', 
@@ -1243,11 +1268,11 @@ sub current_test {
             }
         }
         # If backward, wipe history.  Its their funeral.
-        elsif( $num < @Test_Results ) {
-            $#Test_Results = $num - 1;
+        elsif( $num < @$test_results ) {
+            $#{$test_results} = $num - 1;
         }
     }
-    return $Curr_Test;
+    return $self->{Curr_Test};
 }
 
 
@@ -1265,7 +1290,7 @@ Of course, test #1 is $tests[0], etc...
 sub summary {
     my($self) = shift;
 
-    return map { $_->{'ok'} } @Test_Results;
+    return map { $_->{'ok'} } @{ $self->{Test_Results} };
 }
 
 =item B<details>
@@ -1318,7 +1343,8 @@ result in this structure:
 =cut
 
 sub details {
-    return @Test_Results;
+    my $self = shift;
+    return @{ $self->{Test_Results} };
 }
 
 =item B<todo>
@@ -1331,9 +1357,9 @@ will be considered 'todo' (see Test::More and Test::Harness for
 details).  Returns the reason (ie. the value of $TODO) if running as
 todo tests, false otherwise.
 
-todo() is pretty part about finding the right package to look for
-$TODO in.  It uses the exported_to() package to find it.  If that's
-not set, it's pretty good at guessing the right package to look at.
+todo() is about finding the right package to look for $TODO in.  It
+uses the exported_to() package to find it.  If that's not set, it's
+pretty good at guessing the right package to look at based on $Level.
 
 Sometimes there is some confusion about where todo() should be looking
 for the $TODO variable.  If you want to be sure, tell it explicitly
@@ -1344,7 +1370,8 @@ what $pack to use.
 sub todo {
     my($self, $pack) = @_;
 
-    $pack = $pack || $self->exported_to || $self->caller(1);
+    $pack = $pack || $self->exported_to || $self->caller($Level);
+    return 0 unless $pack;
 
     no strict 'refs';
     return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'}
@@ -1379,7 +1406,7 @@ sub caller {
 
 =item B<_sanity_check>
 
-  _sanity_check();
+  $self->_sanity_check();
 
 Runs a bunch of end of test sanity checks to make sure reality came
 through ok.  If anything is wrong it will die with a fairly friendly
@@ -1389,10 +1416,12 @@ error message.
 
 #'#
 sub _sanity_check {
-    _whoa($Curr_Test < 0,  'Says here you ran a negative number of tests!');
-    _whoa(!$Have_Plan and $Curr_Test, 
+    my $self = shift;
+
+    _whoa($self->{Curr_Test} < 0,  'Says here you ran a negative number of tests!');
+    _whoa(!$self->{Have_Plan} and $self->{Curr_Test}, 
           'Somehow your tests ran without a plan!');
-    _whoa($Curr_Test != @Test_Results,
+    _whoa($self->{Curr_Test} != @{ $self->{Test_Results} },
           'Somehow you got a different number of results than tests ran!');
 }
 
@@ -1449,65 +1478,70 @@ $SIG{__DIE__} = sub {
     for( my $stack = 1;  my $sub = (CORE::caller($stack))[3];  $stack++ ) {
         $in_eval = 1 if $sub =~ /^\(eval\)/;
     }
-    $Test_Died = 1 unless $in_eval;
+    $Test->{Test_Died} = 1 unless $in_eval;
 };
 
 sub _ending {
     my $self = shift;
 
-    _sanity_check();
+    $self->_sanity_check();
 
     # Don't bother with an ending if this is a forked copy.  Only the parent
     # should do the ending.
-    do{ _my_exit($?) && return } if $Original_Pid != $$;
-
-    # Bailout if plan() was never called.  This is so
-    # "require Test::Simple" doesn't puke.
-    do{ _my_exit(0) && return } if !$Have_Plan && !$Test_Died;
+    # Exit if plan() was never called.  This is so "require Test::Simple" 
+    # doesn't puke.
+    if( ($self->{Original_Pid} != $$) or
+       (!$self->{Have_Plan} && !$self->{Test_Died}) )
+    {
+       _my_exit($?);
+       return;
+    }
 
     # Figure out if we passed or failed and print helpful messages.
-    if( @Test_Results ) {
+    my $test_results = $self->{Test_Results};
+    if( @$test_results ) {
         # The plan?  We have no plan.
-        if( $No_Plan ) {
-            $self->_print("1..$Curr_Test\n") unless $self->no_header;
-            $Expected_Tests = $Curr_Test;
+        if( $self->{No_Plan} ) {
+            $self->_print("1..$self->{Curr_Test}\n") unless $self->no_header;
+            $self->{Expected_Tests} = $self->{Curr_Test};
         }
 
         # Auto-extended arrays and elements which aren't explicitly
         # filled in with a shared reference will puke under 5.8.0
         # ithreads.  So we have to fill them in by hand. :(
         my $empty_result = &share({});
-        for my $idx ( 0..$Expected_Tests-1 ) {
-            $Test_Results[$idx] = $empty_result
-              unless defined $Test_Results[$idx];
+        for my $idx ( 0..$self->{Expected_Tests}-1 ) {
+            $test_results->[$idx] = $empty_result
+              unless defined $test_results->[$idx];
         }
 
-        my $num_failed = grep !$_->{'ok'}, @Test_Results[0..$Expected_Tests-1];
-        $num_failed += abs($Expected_Tests - @Test_Results);
+        my $num_failed = grep !$_->{'ok'}, 
+                              @{$test_results}[0..$self->{Expected_Tests}-1];
+        $num_failed += abs($self->{Expected_Tests} - @$test_results);
 
-        if( $Curr_Test < $Expected_Tests ) {
-            my $s = $Expected_Tests == 1 ? '' : 's';
+        if( $self->{Curr_Test} < $self->{Expected_Tests} ) {
+            my $s = $self->{Expected_Tests} == 1 ? '' : 's';
             $self->diag(<<"FAIL");
-Looks like you planned $Expected_Tests test$s but only ran $Curr_Test.
+Looks like you planned $self->{Expected_Tests} test$s but only ran $self->{Curr_Test}.
 FAIL
         }
-        elsif( $Curr_Test > $Expected_Tests ) {
-            my $num_extra = $Curr_Test - $Expected_Tests;
-            my $s = $Expected_Tests == 1 ? '' : 's';
+        elsif( $self->{Curr_Test} > $self->{Expected_Tests} ) {
+            my $num_extra = $self->{Curr_Test} - $self->{Expected_Tests};
+            my $s = $self->{Expected_Tests} == 1 ? '' : 's';
             $self->diag(<<"FAIL");
-Looks like you planned $Expected_Tests test$s but ran $num_extra extra.
+Looks like you planned $self->{Expected_Tests} test$s but ran $num_extra extra.
 FAIL
         }
         elsif ( $num_failed ) {
             my $s = $num_failed == 1 ? '' : 's';
             $self->diag(<<"FAIL");
-Looks like you failed $num_failed test$s of $Expected_Tests.
+Looks like you failed $num_failed test$s of $self->{Expected_Tests}.
 FAIL
         }
 
-        if( $Test_Died ) {
+        if( $self->{Test_Died} ) {
             $self->diag(<<"FAIL");
-Looks like your test died just after $Curr_Test.
+Looks like your test died just after $self->{Curr_Test}.
 FAIL
 
             _my_exit( 255 ) && return;
@@ -1515,10 +1549,10 @@ FAIL
 
         _my_exit( $num_failed <= 254 ? $num_failed : 254  ) && return;
     }
-    elsif ( $Skip_All ) {
+    elsif ( $self->{Skip_All} ) {
         _my_exit( 0 ) && return;
     }
-    elsif ( $Test_Died ) {
+    elsif ( $self->{Test_Died} ) {
         $self->diag(<<'FAIL');
 Looks like your test died before it could output anything.
 FAIL
index aa02808..a40ae4b 100644 (file)
@@ -18,7 +18,7 @@ sub _carp {
 
 require Exporter;
 use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO);
-$VERSION = '0.54';
+$VERSION = '0.60';
 $VERSION = eval $VERSION;    # make the alpha version come out as a number
 
 @ISA    = qw(Exporter);
@@ -100,11 +100,6 @@ Test::More - yet another framework for writing test scripts
   pass($test_name);
   fail($test_name);
 
-  # Utility comparison functions.
-  eq_array(\@this, \@that);
-  eq_hash(\%this, \%that);
-  eq_set(\@this, \@that);
-
   # UNIMPLEMENTED!!!
   my @status = Test::More::status;
 
@@ -805,7 +800,7 @@ sub _is_module_name {
     # End with an alphanumeric.
     # The rest is an alphanumeric or ::
     $module =~ s/\b::\b//g;
-    $module =~ /^[a-zA-Z]\w+$/;
+    $module =~ /^[a-zA-Z]\w*$/;
 }
 
 =back
@@ -982,11 +977,11 @@ but want to put tests in your testing script (always a good idea).
 
 =back
 
-=head2 Comparison functions
+=head2 Complex data structures
 
 Not everything is a simple eq check or regex.  There are times you
-need to see if two arrays are equivalent, for instance.  For these
-instances, Test::More provides a handful of useful functions.
+need to see if two data structures are equivalent.  For these
+instances Test::More provides a handful of useful functions.
 
 B<NOTE> I'm not quite sure what will happen with filehandles.
 
@@ -1018,26 +1013,28 @@ WARNING
         chop $msg;   # clip off newline so carp() will put in line/file
 
         _carp sprintf $msg, scalar @_;
+
+       return $Test->ok(0);
     }
 
     my($this, $that, $name) = @_;
 
     my $ok;
-    if( !ref $this xor !ref $that ) {  # one's a reference, one isn't
-        $ok = 0;
-    }
-    if( !ref $this and !ref $that ) {
+    if( !ref $this and !ref $that ) {                  # neither is a reference
         $ok = $Test->is_eq($this, $that, $name);
     }
-    else {
+    elsif( !ref $this xor !ref $that ) {       # one's a reference, one isn't
+        $ok = $Test->ok(0, $name);
+       $Test->diag( _format_stack({ vals => [ $this, $that ] }) );
+    }
+    else {                                     # both references
         local @Data_Stack = ();
-        local %Refs_Seen  = ();
         if( _deep_check($this, $that) ) {
             $ok = $Test->ok(1, $name);
         }
         else {
             $ok = $Test->ok(0, $name);
-            $ok = $Test->diag(_format_stack(@Data_Stack));
+            $Test->diag(_format_stack(@Data_Stack));
         }
     }
 
@@ -1073,9 +1070,10 @@ sub _format_stack {
     my $out = "Structures begin differing at:\n";
     foreach my $idx (0..$#vals) {
         my $val = $vals[$idx];
-        $vals[$idx] = !defined $val ? 'undef' : 
-                      $val eq $DNE  ? "Does not exist"
-                                    : "'$val'";
+        $vals[$idx] = !defined $val ? 'undef'          :
+                      $val eq $DNE  ? "Does not exist" :
+                     ref $val      ? "$val"           :
+                                      "'$val'";
     }
 
     $out .= "$vars[0] = $vals[0]\n";
@@ -1099,9 +1097,28 @@ sub _type {
 }
 
 
+=head2 Discouraged comparison functions
+
+The use of the following functions is discouraged as they are not
+actually testing functions and produce no diagnostics to help figure
+out what went wrong.  They were written before is_deeply() existed
+because I couldn't figure out how to display a useful diff of two
+arbitrary data structures.
+
+These functions are usually used inside an ok().
+
+    ok( eq_array(\@this, \@that) );
+
+C<is_deeply()> can do that better and with diagnostics.  
+
+    is_deeply( \@this, \@that );
+
+They may be deprecated in future versions.
+
+
 =item B<eq_array>
 
-  eq_array(\@this, \@that);
+  my $is_eq = eq_array(\@this, \@that);
 
 Checks if two arrays are equivalent.  This is a deep check, so
 multi-level structures are handled correctly.
@@ -1111,8 +1128,7 @@ multi-level structures are handled correctly.
 #'#
 sub eq_array {
     local @Data_Stack;
-    local %Refs_Seen;
-    _eq_array(@_);
+    _deep_check(@_);
 }
 
 sub _eq_array  {
@@ -1125,13 +1141,6 @@ sub _eq_array  {
 
     return 1 if $a1 eq $a2;
 
-    if($Refs_Seen{$a1}) {
-        return $Refs_Seen{$a1} eq $a2;
-    }
-    else {
-        $Refs_Seen{$a1} = "$a2";
-    }
-
     my $ok = 1;
     my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2;
     for (0..$max) {
@@ -1152,6 +1161,11 @@ sub _deep_check {
     my($e1, $e2) = @_;
     my $ok = 0;
 
+    # Effectively turn %Refs_Seen into a stack.  This avoids picking up
+    # the same referenced used twice (such as [\$a, \$a]) to be considered
+    # circular.
+    local %Refs_Seen = %Refs_Seen;
+
     {
         # Quiet uninitialized value warnings when comparing undefs.
         local $^W = 0; 
@@ -1160,6 +1174,7 @@ sub _deep_check {
 
         # Either they're both references or both not.
         my $same_ref = !(!ref $e1 xor !ref $e2);
+       my $not_ref  = (!ref $e1 and !ref $e2);
 
         if( defined $e1 xor defined $e2 ) {
             $ok = 0;
@@ -1170,12 +1185,23 @@ sub _deep_check {
         elsif ( $same_ref and ($e1 eq $e2) ) {
             $ok = 1;
         }
+       elsif ( $not_ref ) {
+           push @Data_Stack, { type => '', vals => [$e1, $e2] };
+           $ok = 0;
+       }
         else {
+            if( $Refs_Seen{$e1} ) {
+                return $Refs_Seen{$e1} eq $e2;
+            }
+            else {
+                $Refs_Seen{$e1} = "$e2";
+            }
+
             my $type = _type($e1);
-            $type = '' unless _type($e2) eq $type;
+            $type = 'DIFFERENT' unless _type($e2) eq $type;
 
-            if( !$type ) {
-                push @Data_Stack, { vals => [$e1, $e2] };
+            if( $type eq 'DIFFERENT' ) {
+                push @Data_Stack, { type => $type, vals => [$e1, $e2] };
                 $ok = 0;
             }
             elsif( $type eq 'ARRAY' ) {
@@ -1185,7 +1211,7 @@ sub _deep_check {
                 $ok = _eq_hash($e1, $e2);
             }
             elsif( $type eq 'REF' ) {
-                push @Data_Stack, { type => 'REF', vals => [$e1, $e2] };
+                push @Data_Stack, { type => $type, vals => [$e1, $e2] };
                 $ok = _deep_check($$e1, $$e2);
                 pop @Data_Stack if $ok;
             }
@@ -1194,6 +1220,9 @@ sub _deep_check {
                 $ok = _deep_check($$e1, $$e2);
                 pop @Data_Stack if $ok;
             }
+           else {
+               _whoa(1, "No type in _deep_check");
+           }
         }
     }
 
@@ -1201,9 +1230,20 @@ sub _deep_check {
 }
 
 
+sub _whoa {
+    my($check, $desc) = @_;
+    if( $check ) {
+        die <<WHOA;
+WHOA!  $desc
+This should never happen!  Please contact the author immediately!
+WHOA
+    }
+}
+
+
 =item B<eq_hash>
 
-  eq_hash(\%this, \%that);
+  my $is_eq = eq_hash(\%this, \%that);
 
 Determines if the two hashes contain the same keys and values.  This
 is a deep check.
@@ -1212,8 +1252,7 @@ is a deep check.
 
 sub eq_hash {
     local @Data_Stack;
-    local %Refs_Seen;
-    return _eq_hash(@_);
+    return _deep_check(@_);
 }
 
 sub _eq_hash {
@@ -1226,13 +1265,6 @@ sub _eq_hash {
 
     return 1 if $a1 eq $a2;
 
-    if( $Refs_Seen{$a1} ) {
-        return $Refs_Seen{$a1} eq $a2;
-    }
-    else {
-        $Refs_Seen{$a1} = "$a2";
-    }
-
     my $ok = 1;
     my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2;
     foreach my $k (keys %$bigger) {
@@ -1251,15 +1283,23 @@ sub _eq_hash {
 
 =item B<eq_set>
 
-  eq_set(\@this, \@that);
+  my $is_eq = eq_set(\@this, \@that);
 
 Similar to eq_array(), except the order of the elements is B<not>
 important.  This is a deep check, but the irrelevancy of order only
 applies to the top level.
 
+    ok( eq_set(\@this, \@that) );
+
+Is better written:
+
+    is_deeply( [sort @this], [sort @that] );
+
 B<NOTE> By historical accident, this is not a true set comparision.
 While the order of elements does not matter, duplicate elements do.
 
+Test::Deep contains much better set comparison functions.
+
 =cut
 
 sub eq_set  {
@@ -1330,6 +1370,8 @@ So the exit codes are...
 
 If you fail more than 254 tests, it will be reported as 254.
 
+B<NOTE>  This behavior may go away in future versions.
+
 
 =head1 CAVEATS and NOTES
 
index 05b4dd5..f84ac5e 100644 (file)
@@ -4,7 +4,7 @@ use 5.004;
 
 use strict 'vars';
 use vars qw($VERSION);
-$VERSION = '0.54';
+$VERSION = '0.60';
 $VERSION = eval $VERSION;    # make the alpha version come out as a number
 
 
@@ -130,7 +130,7 @@ Here's an example of a simple .t file for the fictional Film module.
                              Rating   => 'R',
                              NumExplodingSheep => 1
                            });
-    ok( defined($btaste) and ref $btaste eq 'Film',     'new() works' );
+    ok( defined($btaste) && ref $btaste eq 'Film,     'new() works' );
 
     ok( $btaste->Title      eq 'Bad Taste',     'Title() get'    );
     ok( $btaste->Director   eq 'Peter Jackson', 'Director() get' );
index f9e6483..d046129 100644 (file)
@@ -1,3 +1,24 @@
+0.60  Tue May  3 14:20:34 PDT 2005
+
+0.59_01  Tue Apr 26 21:51:12 PDT 2005
+    * Test::Builder now has a create() method which allows you to create
+      a brand spanking new Test::Builder object.
+    * require_ok() was not working for single letter module names.
+    * is_deeply() and eq_* now work with circular scalar references
+      (Thanks Fergal)
+    * Use of eq_* now officially discouraged.
+    - Removed eq_* from the SYNOPSIS.
+    - is_deeply(undef, $not_undef); now works. [rt.cpan.org 9441]
+    - is_deeply() was mistakenly interpeting the same reference used twice
+      in a data structure as being circular causing failures.
+      [rt.cpan.org 11623]
+    - Loading Test::Builder but not using it would interfere with the
+      exit code if the code exited. [rt.cpan.org 12310]
+    - is_deeply() diagnostics now disambiguate between stringified references
+      and references. [rt.cpan.org 8865]
+    - Files opened by the output methods are now autoflushed.
+    - todo() now honors $Level when looking for $TODO.
+
 0.54  Wed Dec 15 04:18:43 EST 2004
     * $how_many is optional for skip() and todo_skip().  Thanks to 
       Devel::Cover for pointing this out.
index 3032dc7..778faa3 100644 (file)
@@ -25,7 +25,9 @@ else {
 my $ret = Module::Signature::verify();
 SKIP: {
     skip "Module::Signature cannot verify", 1 
-      if $ret eq Module::Signature::CANNOT_VERIFY();
+      if $ret eq Module::Signature::CANNOT_VERIFY()   or
+         $ret eq Module::Signature::CIPHER_UNKNOWN();
 
     cmp_ok $ret, '==', Module::Signature::SIGNATURE_OK(), "Valid signature";
 }
+
index d7d17dc..2fd819e 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
 }
 
 use strict;
-use Test::More tests => 5;
+use Test::More tests => 11;
 
 my $a1 = [ 1, 2, 3 ];
 push @$a1, $a1;
@@ -31,3 +31,41 @@ $h2->{4} = $h2;
 
 is_deeply $h1, $h2;
 ok( eq_hash  ($h1, $h2) );
+
+my ($r, $s);
+
+$r = \$r;
+$s = \$s;
+
+ok( eq_array ([$s], [$r]) );
+
+
+{
+    # Classic set of circular scalar refs.
+    my($a,$b,$c);
+    $a = \$b;
+    $b = \$c;
+    $c = \$a;
+
+    my($d,$e,$f);
+    $d = \$e;
+    $e = \$f;
+    $f = \$d;
+
+    is_deeply( $a, $a );
+    is_deeply( $a, $d );
+}
+
+
+{
+    # rt.cpan.org 11623
+    # Make sure the circular ref checks don't get confused by a reference 
+    # which is simply repeating.
+    my $a = {};
+    my $b = {};
+    my $c = {};
+
+    is_deeply( [$a, $a], [$b, $c] );
+    is_deeply( { foo => $a, bar => $a }, { foo => $b, bar => $c } );
+    is_deeply( [\$a, \$a], [\$b, \$c] );
+}
index 0ba76ba..0e30ce7 100644 (file)
@@ -58,6 +58,7 @@ my %Tests = (
              'pre_plan_death.plx'       => ['not zero',    'not zero'],
              'death_in_eval.plx'        => [0,      0],
              'require.plx'              => [0,      0],
+            'exit.plx'                 => [1,      4],
             );
 
 print "1..".keys(%Tests)."\n";
index ca103b1..55d7aec 100644 (file)
@@ -10,7 +10,13 @@ BEGIN {
 use Test::More;
 use Config;
 
-if( !$Config{d_fork} ) {
+my $Can_Fork = $Config{d_fork} ||
+               (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+                $Config{useithreads} and 
+                $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/
+               );
+
+if( !$Can_Fork ) {
     plan skip_all => "This system cannot fork";
 }
 else {
@@ -23,3 +29,4 @@ if( fork ) { # parent
 else {
     exit;   # child
 }
+
index d3f888f..d0be86a 100644 (file)
@@ -14,10 +14,10 @@ my $unplanned;
 
 BEGIN {
        $unplanned = 'oops';
-       $unplanned = Test::Builder->has_plan;
+       $unplanned = Test::Builder->new->has_plan;
 };
 
 use Test::More tests => 2;
 
 is($unplanned, undef, 'no plan yet defined');
-is(Test::Builder->has_plan, 2, 'has fixed plan');
+is(Test::Builder->new->has_plan, 2, 'has fixed plan');
index b988737..33e0923 100644 (file)
@@ -31,4 +31,4 @@ use strict;
 use Test::Builder;
 
 plan 'no_plan';
-is(Test::Builder->has_plan, 'no_plan', 'has no_plan');
+is(Test::Builder->new->has_plan, 'no_plan', 'has no_plan');
diff --git a/lib/Test/Simple/t/is_deeply.t b/lib/Test/Simple/t/is_deeply.t
deleted file mode 100644 (file)
index c6b1625..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/perl -w
-
-BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        chdir 't';
-        @INC = ('../lib', 'lib');
-    }
-    else {
-        unshift @INC, 't/lib';
-    }
-}
-
-use strict;
-
-use Test::Builder;
-require Test::Simple::Catch;
-my($out, $err) = Test::Simple::Catch::caught();
-Test::Builder->new->no_header(1);
-Test::Builder->new->no_ending(1);
-local $ENV{HARNESS_ACTIVE} = 0;
-
-
-# Can't use Test.pm, that's a 5.005 thing.
-package main;
-
-print "1..38\n";
-
-my $test_num = 1;
-# Utility testing functions.
-sub ok ($;$) {
-    my($test, $name) = @_;
-    my $ok = '';
-    $ok .= "not " unless $test;
-    $ok .= "ok $test_num";
-    $ok .= " - $name" if defined $name;
-    $ok .= "\n";
-    print $ok;
-    $test_num++;
-
-    return $test;
-}
-
-sub is ($$;$) {
-    my($this, $that, $name) = @_;
-    my $test = $$this eq $that;
-    my $ok = '';
-    $ok .= "not " unless $test;
-    $ok .= "ok $test_num";
-    $ok .= " - $name" if defined $name;
-    $ok .= "\n";
-    print $ok;
-
-    unless( $test ) {
-        print "# got      \n$$this";
-        print "# expected \n$that";
-    }
-    $test_num++;
-
-    $$this = '';
-
-    return $test;
-}
-
-sub like ($$;$) {
-    my($this, $regex, $name) = @_;
-
-    $regex = qr/$regex/ unless ref $regex;
-    my $test = $$this =~ $regex;
-
-    my $ok = '';
-    $ok .= "not " unless $test;
-    $ok .= "ok $test_num";
-    $ok .= " - $name" if defined $name;
-    $ok .= "\n";
-    print $ok;
-
-    unless( $test ) {
-        print "# got      \n$$this";
-        print "# expected \n$regex";
-    }
-    $test_num++;
-
-    $$this = '';
-
-
-    return $test;
-}
-
-
-require Test::More;
-Test::More->import(tests => 11, import => ['is_deeply']);
-
-my $Filename = quotemeta $0;
-
-#line 68
-is_deeply('foo', 'bar', 'plain strings');
-is( $out, "not ok 1 - plain strings\n",     'plain strings' );
-is( $err, <<ERR,                            '    right diagnostic' );
-#     Failed test ($0 at line 68)
-#          got: 'foo'
-#     expected: 'bar'
-ERR
-
-
-#line 78
-is_deeply({}, [], 'different types');
-is( $out, "not ok 2 - different types\n",   'different types' );
-like( $err, <<ERR,                          '   right diagnostic' );
-#     Failed test \\($Filename at line 78\\)
-#     Structures begin differing at:
-#          \\\$got = 'HASH\\(0x[0-9a-f]+\\)'
-#     \\\$expected = 'ARRAY\\(0x[0-9a-f]+\\)'
-ERR
-
-#line 88
-is_deeply({ this => 42 }, { this => 43 }, 'hashes with different values');
-is( $out, "not ok 3 - hashes with different values\n", 
-                                        'hashes with different values' );
-is( $err, <<ERR,                        '   right diagnostic' );
-#     Failed test ($0 at line 88)
-#     Structures begin differing at:
-#          \$got->{this} = '42'
-#     \$expected->{this} = '43'
-ERR
-
-#line 99
-is_deeply({ that => 42 }, { this => 42 }, 'hashes with different keys');
-is( $out, "not ok 4 - hashes with different keys\n",
-                                        'hashes with different keys' );
-is( $err, <<ERR,                        '    right diagnostic' );
-#     Failed test ($0 at line 99)
-#     Structures begin differing at:
-#          \$got->{this} = Does not exist
-#     \$expected->{this} = '42'
-ERR
-
-#line 110
-is_deeply([1..9], [1..10],    'arrays of different length');
-is( $out, "not ok 5 - arrays of different length\n",
-                                        'arrays of different length' );
-is( $err, <<ERR,                        '    right diagnostic' );
-#     Failed test ($0 at line 110)
-#     Structures begin differing at:
-#          \$got->[9] = Does not exist
-#     \$expected->[9] = '10'
-ERR
-
-#line 121
-is_deeply([undef, undef], [undef], 'arrays of undefs' );
-is( $out, "not ok 6 - arrays of undefs\n",  'arrays of undefs' );
-is( $err, <<ERR,                            '    right diagnostic' );
-#     Failed test ($0 at line 121)
-#     Structures begin differing at:
-#          \$got->[1] = undef
-#     \$expected->[1] = Does not exist
-ERR
-
-#line 131
-is_deeply({ foo => undef }, {},    'hashes of undefs' );
-is( $out, "not ok 7 - hashes of undefs\n",  'hashes of undefs' );
-is( $err, <<ERR,                            '    right diagnostic' );
-#     Failed test ($0 at line 131)
-#     Structures begin differing at:
-#          \$got->{foo} = undef
-#     \$expected->{foo} = Does not exist
-ERR
-
-#line 141
-is_deeply(\42, \23,   'scalar refs');
-is( $out, "not ok 8 - scalar refs\n",   'scalar refs' );
-is( $err, <<ERR,                        '    right diagnostic' );
-#     Failed test ($0 at line 141)
-#     Structures begin differing at:
-#     \${     \$got} = '42'
-#     \${\$expected} = '23'
-ERR
-
-#line 151
-is_deeply([], \23,    'mixed scalar and array refs');
-is( $out, "not ok 9 - mixed scalar and array refs\n",
-                                        'mixed scalar and array refs' );
-like( $err, <<ERR,                      '    right diagnostic' );
-#     Failed test \\($Filename at line 151\\)
-#     Structures begin differing at:
-#          \\\$got = 'ARRAY\\(0x[0-9a-f]+\\)'
-#     \\\$expected = 'SCALAR\\(0x[0-9a-f]+\\)'
-ERR
-
-
-my($a1, $a2, $a3);
-$a1 = \$a2;  $a2 = \$a3;
-$a3 = 42;
-
-my($b1, $b2, $b3);
-$b1 = \$b2;  $b2 = \$b3;
-$b3 = 23;
-
-#line 173
-is_deeply($a1, $b1, 'deep scalar refs');
-is( $out, "not ok 10 - deep scalar refs\n",     'deep scalar refs' );
-is( $err, <<ERR,                              '    right diagnostic' );
-#     Failed test ($0 at line 173)
-#     Structures begin differing at:
-#     \${\${     \$got}} = '42'
-#     \${\${\$expected}} = '23'
-ERR
-
-# I don't know how to properly display this structure.
-# $a2 = { foo => \$a3 };
-# $b2 = { foo => \$b3 };
-# is_deeply([$a1], [$b1], 'deep mixed scalar refs');
-
-my $foo = {
-           this => [1..10],
-           that => { up => "down", left => "right" },
-          };
-
-my $bar = {
-           this => [1..10],
-           that => { up => "down", left => "right", foo => 42 },
-          };
-
-#line 198
-is_deeply( $foo, $bar, 'deep structures' );
-ok( @Test::More::Data_Stack == 0, '@Data_Stack not holding onto things' );
-is( $out, "not ok 11 - deep structures\n",  'deep structures' );
-is( $err, <<ERR,                            '    right diagnostic' );
-#     Failed test ($0 at line 198)
-#     Structures begin differing at:
-#          \$got->{that}{foo} = Does not exist
-#     \$expected->{that}{foo} = '42'
-ERR
-
-
-#line 221
-my @tests = ([],
-             [qw(42)],
-             [qw(42 23), qw(42 23)]
-            );
-
-foreach my $test (@tests) {
-    my $num_args = @$test;
-
-    my $warning;
-    local $SIG{__WARN__} = sub { $warning .= join '', @_; };
-    is_deeply(@$test);
-
-    like \$warning, 
-         qr/^is_deeply\(\) takes two or three args, you gave $num_args\.\n/;
-}
-
-
-#line 240
-# [rt.cpan.org 6837]
-ok !is_deeply([{Foo => undef}],[{Foo => ""}]), 'undef != ""';
-ok( @Test::More::Data_Stack == 0, '@Data_Stack not holding onto things' );
-
-
-#line 258
-# [rt.cpan.org 7031]
-my $a = [];
-ok !is_deeply($a, $a.''),       "don't compare refs like strings";
-ok !is_deeply([$a], [$a.'']),   "  even deep inside";
-
-
-#line 265
-# [rt.cpan.org 7030]
-ok !is_deeply( {}, {key => []} ),  '[] could match non-existent values';
-ok !is_deeply( [], [[]] );
-
-
-#line 273
-$$err = $$out = '';
-is_deeply( [\'a', 'b'], [\'a', 'c'] );
-is( $out, "not ok 20\n",  'scalar refs in an array' );
-is( $err, <<ERR,        '    right diagnostic' );
-#     Failed test ($0 at line 274)
-#     Structures begin differing at:
-#          \$got->[1] = 'b'
-#     \$expected->[1] = 'c'
-ERR
-
-
-#line 285
-my $ref = \23;
-is_deeply( 23, $ref );
-is( $out, "not ok 21\n", 'scalar vs ref' );
-is( $err, <<ERR,        '  right diagnostic');
-#     Failed test ($0 at line 286)
-#     Structures begin differing at:
-#          \$got = '23'
-#     \$expected = '$ref'
-ERR
-
-#line 296
-is_deeply( $ref, 23 );
-is( $out, "not ok 22\n", 'ref vs scalar' );
-is( $err, <<ERR,        '  right diagnostic');
-#     Failed test ($0 at line 296)
-#     Structures begin differing at:
-#          \$got = '$ref'
-#     \$expected = '23'
-ERR
index f3da6b7..a1c201c 100644 (file)
@@ -11,17 +11,19 @@ BEGIN {
 }
 
 use strict;
-use Test::More tests => 6;
+use Test::More tests => 8;
 use TieOut;
 
 ok( !Test::Builder::_is_fh("foo"), 'string is not a filehandle' );
+ok( !Test::Builder::_is_fh(''),    'empty string' );
+ok( !Test::Builder::_is_fh(undef), 'undef' );
 
 ok( open(FILE, '>foo') );
-END { unlink 'foo' }
+END { close FILE; unlink 'foo' }
 
 ok( Test::Builder::_is_fh(*FILE) );
 ok( Test::Builder::_is_fh(\*FILE) );
 ok( Test::Builder::_is_fh(*FILE{IO}) );
 
 tie *OUT, 'TieOut';
-ok( Test::Builder::_is_fh(*OUT) );
\ No newline at end of file
+ok( Test::Builder::_is_fh(*OUT) );
index 269b951..463a007 100644 (file)
@@ -11,7 +11,7 @@ BEGIN {
 }
 
 use strict;
-use Test::More tests => 7;
+use Test::More tests => 8;
 
 # Symbol and Class::Struct are both non-XS core modules back to 5.004.
 # So they'll always be there.
@@ -26,3 +26,4 @@ ok( $INC{'Class/Struct.pm'},    "require_ok FILE" );
 ok !Test::More::_is_module_name('foo:bar');
 ok !Test::More::_is_module_name('foo/bar.thing');
 ok !Test::More::_is_module_name('Foo::Bar::');
+ok Test::More::_is_module_name('V');