package Test::Valgrind::Action::Test; use strict; use warnings; =head1 NAME Test::Valgrind::Action::Test - Test that an analysis didn't generate any error report. =head1 VERSION Version 1.13 =cut our $VERSION = '1.13'; =head1 DESCRIPTION This action uses C to plan and pass or fail tests according to the reports received. =cut use Test::Builder; use base qw; =head1 METHODS This class inherits L and L. =head2 C<< new diag => $diag, extra_tests => $extra_tests, ... >> Your usual constructor. When C<$diag> is true, the original output of the command and the error reports are intermixed as diagnostics. C<$extra_tests> specifies how many extraneous tests you want to plan in addition to the default ones. Other arguments are passed straight to C<< Test::Valgrind::Action->new >>. =cut sub new { my $class = shift; $class = ref($class) || $class; my %args = @_; my $diag = delete $args{diag}; my $extra_tests = delete $args{extra_tests} || 0; my $self = bless $class->SUPER::new(%args), $class; $self->{diag} = $diag; $self->{extra_tests} = $extra_tests; $self; } =head2 C Read-only accessor for the C option. =cut sub diag { $_[0]->{diag} } =head2 C Returns the list of all the monitored report kinds. =cut sub kinds { @{$_[0]->{kinds} || []} } sub start { my ($self, $sess) = @_; $self->SUPER::start($sess); my @kinds = grep $_ ne 'Diag', $sess->report_class->kinds; $self->{kinds} = \@kinds; $self->{status} = 0; my $tb = Test::Builder->new; $tb->plan(tests => $self->{extra_tests} + scalar @kinds); $self->restore_all_fh; delete $self->{capture}; if ($self->diag) { require File::Temp; $self->{capture} = File::Temp::tempfile(); $self->{capture_pos} = 0; } $self->save_fh(\*STDOUT => '>' => $self->{capture}); $self->save_fh(\*STDERR => '>' => $self->{capture}); return; } sub abort { my ($self, $sess, $msg) = @_; $self->restore_all_fh; my $tb = Test::Builder->new; my $plan = $tb->has_plan; if (defined $plan) { $tb->BAIL_OUT($msg); $self->{status} = 255; } else { $tb->skip_all($msg); $self->{status} = 0; } return; } sub report { my ($self, $sess, $report) = @_; if ($report->is_diag) { my $tb = Test::Builder->new; $tb->diag($report->data); return; } $self->SUPER::report($sess, $report); $self->{reports}->{$report->kind}->{$report->id} = $report; if ($self->diag) { my $tb = Test::Builder->new; my $fh = $self->{capture}; seek $fh, $self->{capture_pos}, 0; $tb->diag($_) while <$fh>; $self->{capture_pos} = tell $fh; $tb->diag($report->dump); } return; } sub finish { my ($self, $sess) = @_; $self->SUPER::finish($sess); my $tb = Test::Builder->new; $self->restore_all_fh; if (my $fh = $self->{capture}) { seek $fh, $self->{capture_pos}, 0; $tb->diag($_) while <$fh>; close $fh or $self->_croak('close(capture[' . fileno($fh) . "]): $!"); delete @{$self}{qw}; } my $failed = 0; for my $kind ($self->kinds) { my $reports = $self->{reports}->{$kind} || { }; my $errors = keys %$reports; $tb->is_num($errors, 0, $kind); if ($errors) { ++$failed; unless ($self->diag) { $tb->diag("\n" . $_->dump) for values %$reports; } } } $self->{status} = $failed < 255 ? $failed : 254; return; } sub status { my ($self, $sess) = @_; $self->SUPER::status($sess); $self->{status}; } =head1 SEE ALSO L, L. =head1 AUTHOR Vincent Pit, C<< >>, L. You can contact me by mail or on C (vincent). =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Test::Valgrind::Action::Test =head1 COPYRIGHT & LICENSE Copyright 2009,2010,2011 Vincent Pit, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; # End of Test::Valgrind::Action::Test