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 )