BioPerl-Network

 view release on metacpan or  search on metacpan

t/lib/Test/Harness/Straps.pm  view on Meta::CPAN


=cut

sub analyze {
    my($self, $name, $test_output) = @_;

    my $it = Test::Harness::Iterator->new($test_output);
    return $self->_analyze_iterator($name, $it);
}


sub _analyze_iterator {
    my($self, $name, $it) = @_;

    $self->_reset_file_state;
    $self->{file} = $name;

    my $results = Test::Harness::Results->new;

    # Set them up here so callbacks can have them.
    $self->{totals}{$name} = $results;
    while( defined(my $line = $it->next) ) {
        $self->_analyze_line($line, $results);
        last if $self->{saw_bailout};
    }

    $results->set_skip_all( $self->{skip_all} ) if defined $self->{skip_all};

    my $passed =
        (($results->max == 0) && defined $results->skip_all) ||
        ($results->max &&
         $results->seen &&
         $results->max == $results->seen &&
         $results->max == $results->ok);

    $results->set_passing( $passed ? 1 : 0 );

    return $results;
}


sub _analyze_line {
    my $self = shift;
    my $line = shift;
    my $results = shift;

    $self->{line}++;

    my $linetype;
    my $point = Test::Harness::Point->from_test_line( $line );
    if ( $point ) {
        $linetype = 'test';

        $results->inc_seen;
        $point->set_number( $self->{'next'} ) unless $point->number;

        # sometimes the 'not ' and the 'ok' are on different lines,
        # happens often on VMS if you do:
        #   print "not " unless $test;
        #   print "ok $num\n";
        if ( $self->{lone_not_line} && ($self->{lone_not_line} == $self->{line} - 1) ) {
            $point->set_ok( 0 );
        }

        if ( $self->{todo}{$point->number} ) {
            $point->set_directive_type( 'todo' );
        }

        if ( $point->is_todo ) {
            $results->inc_todo;
            $results->inc_bonus if $point->ok;
        }
        elsif ( $point->is_skip ) {
            $results->inc_skip;
        }

        $results->inc_ok if $point->pass;

        if ( ($point->number > 100_000) && ($point->number > ($self->{max}||100_000)) ) {
            if ( !$self->{too_many_tests}++ ) {
                warn "Enormous test number seen [test ", $point->number, "]\n";
                warn "Can't detailize, too big.\n";
            }
        }
        else {
            my $details = {
                ok          => $point->pass,
                actual_ok   => $point->ok,
                name        => _def_or_blank( $point->description ),
                type        => _def_or_blank( $point->directive_type ),
                reason      => _def_or_blank( $point->directive_reason ),
            };

            assert( defined( $details->{ok} ) && defined( $details->{actual_ok} ) );
            $results->set_details( $point->number, $details );
        }
    } # test point
    elsif ( $line =~ /^not\s+$/ ) {
        $linetype = 'other';
        # Sometimes the "not " and "ok" will be on separate lines on VMS.
        # We catch this and remember we saw it.
        $self->{lone_not_line} = $self->{line};
    }
    elsif ( $self->_is_header($line) ) {
        $linetype = 'header';

        $self->{saw_header}++;

        $results->inc_max( $self->{max} );
    }
    elsif ( $self->_is_bail_out($line, \$self->{bailout_reason}) ) {
        $linetype = 'bailout';
        $self->{saw_bailout} = 1;
    }
    elsif (my $diagnostics = $self->_is_diagnostic_line( $line )) {
        $linetype = 'other';
        # XXX We can throw this away, really.
        my $test = $results->details->[-1];
        $test->{diagnostics} ||=  '';
        $test->{diagnostics}  .= $diagnostics;
    }
    else {
        $linetype = 'other';
    }

    $self->callback->($self, $line, $linetype, $results) if $self->callback;

    $self->{'next'} = $point->number + 1 if $point;
} # _analyze_line


sub _is_diagnostic_line {
    my ($self, $line) = @_;
    return if index( $line, '# Looks like you failed' ) == 0;
    $line =~ s/^#\s//;
    return $line;
}

=for private $strap->analyze_fh( $name, $test_filehandle )

    my $results = $strap->analyze_fh($name, $test_filehandle);

Like C<analyze>, but it reads from the given filehandle.

=cut

sub analyze_fh {
    my($self, $name, $fh) = @_;

    my $it = Test::Harness::Iterator->new($fh);
    return $self->_analyze_iterator($name, $it);
}

=head2 $strap->analyze_file( $test_file )

    my $results = $strap->analyze_file($test_file);

Like C<analyze>, but it runs the given C<$test_file> and parses its
results.  It will also use that name for the total report.

=cut

t/lib/Test/Harness/Straps.pm  view on Meta::CPAN

    if( my($max, $extra) = $line =~ /^1\.\.(\d+)(.*)/ ) {
        $self->{max}  = $max;
        assert( $self->{max} >= 0,  'Max # of tests looks right' );

        if( defined $extra ) {
            my($todo, $skip, $reason) = $extra =~ /$Extra_Header_Re/xo;

            $self->{todo} = { map { $_ => 1 } split /\s+/, $todo } if $todo;

            if( $self->{max} == 0 ) {
                $reason = '' unless defined $skip and $skip =~ /^Skip/i;
            }

            $self->{skip_all} = $reason;
        }

        return $YES;
    }
    else {
        return $NO;
    }
}

=for private _is_bail_out

  my $is_bail_out = $strap->_is_bail_out($line, \$reason);

Checks if the line is a "Bail out!".  Places the reason for bailing
(if any) in $reason.

=cut

sub _is_bail_out {
    my($self, $line, $reason) = @_;

    if( $line =~ /^Bail out!\s*(.*)/i ) {
        $$reason = $1 if $1;
        return $YES;
    }
    else {
        return $NO;
    }
}

=for private _reset_file_state

  $strap->_reset_file_state;

Resets things like C<< $strap->{max} >> , C<< $strap->{skip_all} >>,
etc. so it's ready to parse the next file.

=cut

sub _reset_file_state {
    my($self) = shift;

    delete @{$self}{qw(max skip_all todo too_many_tests)};
    $self->{line}       = 0;
    $self->{saw_header} = 0;
    $self->{saw_bailout}= 0;
    $self->{lone_not_line} = 0;
    $self->{bailout_reason} = '';
    $self->{'next'}       = 1;
}

=head1 EXAMPLES

See F<examples/mini_harness.plx> for an example of use.

=head1 AUTHOR

Michael G Schwern C<< <schwern at pobox.com> >>, currently maintained by
Andy Lester C<< <andy at petdance.com> >>.

=head1 SEE ALSO

L<Test::Harness>

=cut

sub _def_or_blank {
    return $_[0] if defined $_[0];
    return "";
}

sub set_callback {
    my $self = shift;
    $self->{callback} = shift;
}

sub callback {
    my $self = shift;
    return $self->{callback};
}

1;



( run in 1.754 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )