eaiovnaovbqoebvqoeavibavo Result/Test.pm000064400000006540147635403050007313 0ustar00package App::Prove::State::Result::Test; use strict; use vars qw($VERSION); =head1 NAME App::Prove::State::Result::Test - Individual test results. =head1 VERSION Version 3.28 =cut $VERSION = '3.28'; =head1 DESCRIPTION The C command supports a C<--state> option that instructs it to store persistent state across runs. This module encapsulates the results for a single test. =head1 SYNOPSIS # Re-run failed tests $ prove --state=failed,save -rbv =cut my %methods = ( name => { method => 'name' }, elapsed => { method => 'elapsed', default => 0 }, gen => { method => 'generation', default => 1 }, last_pass_time => { method => 'last_pass_time', default => undef }, last_fail_time => { method => 'last_fail_time', default => undef }, last_result => { method => 'result', default => 0 }, last_run_time => { method => 'run_time', default => undef }, last_todo => { method => 'num_todo', default => 0 }, mtime => { method => 'mtime', default => undef }, seq => { method => 'sequence', default => 1 }, total_passes => { method => 'total_passes', default => 0 }, total_failures => { method => 'total_failures', default => 0 }, parser => { method => 'parser' }, ); while ( my ( $key, $description ) = each %methods ) { my $default = $description->{default}; no strict 'refs'; *{ $description->{method} } = sub { my $self = shift; if (@_) { $self->{$key} = shift; return $self; } return $self->{$key} || $default; }; } =head1 METHODS =head2 Class Methods =head3 C =cut sub new { my ( $class, $arg_for ) = @_; $arg_for ||= {}; bless $arg_for => $class; } =head2 Instance Methods =head3 C The name of the test. Usually a filename. =head3 C The total elapsed times the test took to run, in seconds from the epoch.. =head3 C The number for the "generation" of the test run. The first generation is 1 (one) and subsequent generations are 2, 3, etc. =head3 C The last time the test program passed, in seconds from the epoch. Returns C if the program has never passed. =head3 C The last time the test suite failed, in seconds from the epoch. Returns C if the program has never failed. =head3 C Returns the mtime of the test, in seconds from the epoch. =head3 C Returns a hashref of raw test data, suitable for serialization by YAML. =head3 C Currently, whether or not the test suite passed with no 'problems' (such as TODO passed). =head3 C The total time it took for the test to run, in seconds. If C is available, it will have finer granularity. =head3 C The number of tests with TODO directives. =head3 C The order in which this test was run for the given test suite result. =head3 C The number of times the test has passed. =head3 C The number of times the test has failed. =head3 C The underlying parser object. This is useful if you need the full information for the test program. =cut sub raw { my $self = shift; my %raw = %$self; # this is backwards-compatibility hack and is not guaranteed. delete $raw{name}; delete $raw{parser}; return \%raw; } 1; Result.pm000064400000011526147635403050006374 0ustar00package App::Prove::State::Result; use strict; use Carp 'croak'; use App::Prove::State::Result::Test; use vars qw($VERSION); use constant STATE_VERSION => 1; =head1 NAME App::Prove::State::Result - Individual test suite results. =head1 VERSION Version 3.28 =cut $VERSION = '3.28'; =head1 DESCRIPTION The C command supports a C<--state> option that instructs it to store persistent state across runs. This module encapsulates the results for a single test suite run. =head1 SYNOPSIS # Re-run failed tests $ prove --state=failed,save -rbv =cut =head1 METHODS =head2 Class Methods =head3 C my $result = App::Prove::State::Result->new({ generation => $generation, tests => \%tests, }); Returns a new C instance. =cut sub new { my ( $class, $arg_for ) = @_; $arg_for ||= {}; my %instance_data = %$arg_for; # shallow copy $instance_data{version} = $class->state_version; my $tests = delete $instance_data{tests} || {}; my $self = bless \%instance_data => $class; $self->_initialize($tests); return $self; } sub _initialize { my ( $self, $tests ) = @_; my %tests; while ( my ( $name, $test ) = each %$tests ) { $tests{$name} = $self->test_class->new( { %$test, name => $name } ); } $self->tests( \%tests ); return $self; } =head2 C Returns the current version of state storage. =cut sub state_version {STATE_VERSION} =head2 C Returns the name of the class used for tracking individual tests. This class should either subclass from C or provide an identical interface. =cut sub test_class { return 'App::Prove::State::Result::Test'; } my %methods = ( generation => { method => 'generation', default => 0 }, last_run_time => { method => 'last_run_time', default => undef }, ); while ( my ( $key, $description ) = each %methods ) { my $default = $description->{default}; no strict 'refs'; *{ $description->{method} } = sub { my $self = shift; if (@_) { $self->{$key} = shift; return $self; } return $self->{$key} || $default; }; } =head3 C Getter/setter for the "generation" of the test suite run. The first generation is 1 (one) and subsequent generations are 2, 3, etc. =head3 C Getter/setter for the time of the test suite run. =head3 C Returns the tests for a given generation. This is a hashref or a hash, depending on context called. The keys to the hash are the individual test names and the value is a hashref with various interesting values. Each k/v pair might resemble something like this: 't/foo.t' => { elapsed => '0.0428488254547119', gen => '7', last_pass_time => '1219328376.07815', last_result => '0', last_run_time => '1219328376.07815', last_todo => '0', mtime => '1191708862', seq => '192', total_passes => '6', } =cut sub tests { my $self = shift; if (@_) { $self->{tests} = shift; return $self; } my %tests = %{ $self->{tests} }; my @tests = sort { $a->sequence <=> $b->sequence } values %tests; return wantarray ? @tests : \@tests; } =head3 C my $test = $result->test('t/customer/create.t'); Returns an individual C instance for the given test name (usually the filename). Will return a new C instance if the name is not found. =cut sub test { my ( $self, $name ) = @_; croak("test() requires a test name") unless defined $name; my $tests = $self->{tests} ||= {}; if ( my $test = $tests->{$name} ) { return $test; } else { my $test = $self->test_class->new( { name => $name } ); $self->{tests}->{$name} = $test; return $test; } } =head3 C Returns an list of test names, sorted by run order. =cut sub test_names { my $self = shift; return map { $_->name } $self->tests; } =head3 C $result->remove($test_name); # remove the test my $test = $result->test($test_name); # fatal error Removes a given test from results. This is a no-op if the test name is not found. =cut sub remove { my ( $self, $name ) = @_; delete $self->{tests}->{$name}; return $self; } =head3 C Returns the number of tests for a given test suite result. =cut sub num_tests { keys %{ shift->{tests} } } =head3 C Returns a hashref of raw results, suitable for serialization by YAML. =cut sub raw { my $self = shift; my %raw = %$self; my %tests; for my $test ( $self->tests ) { $tests{ $test->name } = $test->raw; } $raw{tests} = \%tests; return \%raw; } 1;