# New Ticket Created by  James Keenan 
# Please include the string:  [perl #42975]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42975 >


One of the tests in t/tools/ops2pmutils/08-sort_ops.t has begun to fail.

[li11-226:parrot] 504 $ prove -v t/tools/ops2pmutils/08-sort_ops.t
t/tools/ops2pmutils/08-sort_ops....
OK:  Parrot top directory located
1..91
ok 1 - use Parrot::Ops2pm::Utils;
ok 2 - use Parrot::IO::Capture::Mini;
...
not ok 71 - Got expected warning about ops in neither ops.num or  
ops.skip

#     Failed test (t/tools/ops2pmutils/08-sort_ops.t at line 235)
#                   undef
#     doesn't match '(?-xism:not in ops\.num nor ops\.skip)'
ok 72 - changed back to starting directory after testing
...

Paradoxically, this may be a good thing -- or it may simply indicate  
the limitations of my test.

1.  The test file itself has not been altered since r18040 (Apr 08  
2007).  This failure occurred at r18576 (May 16 2007).

------------------------------------------------------------------------
r18040 | jkeenan | 2007-04-08 10:25:01 -0400 (Sun, 08 Apr 2007) | 8  
lines


2.  The module being tested, lib/Parrot/Ops2pm/Utils.pm, has not  
changed since I originally committed it to trunk, excepting ptc's  
perltidy cleanups.

3.  The code in Parrot::Ops2pm::Utils touched during the failing test  
is this in sort_ops() (edited slightly for clarity):

sub sort_ops {
     my $self = shift;
     for my $el ( @{ $self->{ops}->{OPS} } ) {
         if ( exists $self->{optable}->{ $el->full_name } ) {
             # assign something to $el->{CODE}
         }
         elsif ( exists $self->{skiptable}->{ $el->full_name } ) {
             # assign something to $el->{CODE}
         }
         elsif ( $el->{experimental} ) {
             my $n = $self->{optable}->{ $el->full_name } = ++$self-> 
{max_op_num};
             warn sprintf( "%-25s %-10s experimental, not in ops.num 
\n", $el->full_name, $n )
                 if -e "DEVELOPING";
             # assign something to $el->{CODE}
         }
         else {
             warn sprintf( "%-25s %-10s SKIPPED: not in ops.num nor  
ops.skip\n", $el->full_name, "" )
                 if -e "DEVELOPING";   ##### This is causing a test  
to fail
             # assign something to $el->{CODE}
         }
     }
     @{ $self->{ops}->{OPS} } =
         sort { $a->{CODE} <=> $b->{CODE} } ( @{ $self->{ops}-> 
{OPS} } );
}

4.  This is the failing test:

         my $msg;
         my $tie = tie *STDERR, "Parrot::IO::Capture::Mini"
             or croak "Unable to tie";
         ok( defined $tie, "tie established for testing" );
         ok( $self->sort_ops(), "sort_ops returned successfully" );
         $msg = $tie->READLINE;
         untie *STDERR;
         like(
             $msg,
             qr|not in ops\.num nor ops\.skip|,
             "Got expected warning about ops in neither ops.num or  
ops.skip"
         );

The test asserts, "If 'DEVELOPING' exists [which it does], then any  
ops which is found *neither* in src/ops/ops.num *nor* in src/ops/ 
ops.skip will cause a warning to be generated alerting the developer  
to that situation.  That warning will be captured in $msg, which  
should then match the pattern in the like() test.

The fact that the like() test fails means that $msg, at the very  
least, did *not* match the pattern in the qr|| function in the like()  
test.  In point of fact, $msg is 'undef', which means that no warning  
was thrown by any of the ops tested during this test.  Which in turn  
means that all ops tested were mentioned *either* in src/ops/ops.num  
or in src/ops/ops.skip.

Does that mean we should break out the cigars and champagne?  No.   
Why?  Because the test, as written, entails a little cheat for  
practicality's sake.  Parrot::Ops2pm::Utils has to be passed a list  
of ops:

         my $self = Parrot::Ops2pm::Utils->new(
             {
                 argv    => [EMAIL PROTECTED],
                 script  => "tools/build/ops2pm.pl",
                 nolines => undef,
                 renum   => undef,
             }
         );

... but I didn't provide the constructor with *every* ops (as happens  
in 'make'), but only with a very limited selection of ops:

     local @ARGV = qw(
         src/ops/core.ops
         src/ops/bit.ops
         src/ops/object.ops
     );

Four months ago, this selection of ops was sufficient, i.e., there  
was at least one ops somewhere in those files that was not found in  
either ops.num or ops.skip, and so triggered the warning, which  
caused the test to pass.

My objective in writing the test was, in large part, simply to  
'cover' the code, i.e., to demonstrate that that 'else' block inside  
Parrot::Ops2pm::Utils::sort_ops() could be reached by a Perl  
program.  Only one instance was needed to generate that coverage.

But, apparently due to improvements in the ops by other Parrot  
hackers, those three ops files are no longer sufficient to reach the  
'else' block even once.  So no warning is generated and the code is  
not 'covered' by the test suite in t/tools/ops2pmutils/*.t.

5.  So, can anyone suggest a file in src/ops/*.ops that *would*  
contain an ops found *neither* in ops.num nor in ops.skip?  I would  
then pass that file as an argument to this test; a warning would be  
generated; and the test would once again pass.

Thank you very much.
kid51

Reply via email to