<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package App::Prove::State::Result;

use strict;
use warnings;
use Carp 'croak';

use App::Prove::State::Result::Test;

use constant STATE_VERSION =&gt; 1;

=head1 NAME

App::Prove::State::Result - Individual test suite results.

=head1 VERSION

Version 3.44

=cut

our $VERSION = '3.44';

=head1 DESCRIPTION

The C&lt;prove&gt; command supports a C&lt;--state&gt; 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&lt;new&gt;

    my $result = App::Prove::State::Result-&gt;new({
        generation =&gt; $generation,
        tests      =&gt; \%tests,
    });

Returns a new C&lt;App::Prove::State::Result&gt; instance.

=cut

sub new {
    my ( $class, $arg_for ) = @_;
    $arg_for ||= {};
    my %instance_data = %$arg_for;    # shallow copy
    $instance_data{version} = $class-&gt;state_version;
    my $tests = delete $instance_data{tests} || {};
    my $self = bless \%instance_data =&gt; $class;
    $self-&gt;_initialize($tests);
    return $self;
}

sub _initialize {
    my ( $self, $tests ) = @_;
    my %tests;
    while ( my ( $name, $test ) = each %$tests ) {
        $tests{$name} = $self-&gt;test_class-&gt;new(
            {   %$test,
                name =&gt; $name
            }
        );
    }
    $self-&gt;tests( \%tests );
    return $self;
}

=head2 C&lt;state_version&gt;

Returns the current version of state storage.

=cut

sub state_version {STATE_VERSION}

=head2 C&lt;test_class&gt;

Returns the name of the class used for tracking individual tests.  This class
should either subclass from C&lt;App::Prove::State::Result::Test&gt; or provide an
identical interface.

=cut

sub test_class {
    return 'App::Prove::State::Result::Test';
}

my %methods = (
    generation    =&gt; { method =&gt; 'generation',    default =&gt; 0 },
    last_run_time =&gt; { method =&gt; 'last_run_time', default =&gt; undef },
);

while ( my ( $key, $description ) = each %methods ) {
    my $default = $description-&gt;{default};
    no strict 'refs';
    *{ $description-&gt;{method} } = sub {
        my $self = shift;
        if (@_) {
            $self-&gt;{$key} = shift;
            return $self;
        }
        return $self-&gt;{$key} || $default;
    };
}

=head3 C&lt;generation&gt;

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&lt;last_run_time&gt;

Getter/setter for the time of the test suite run.

=head3 C&lt;tests&gt;

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' =&gt; {
    elapsed        =&gt; '0.0428488254547119',
    gen            =&gt; '7',
    last_pass_time =&gt; '1219328376.07815',
    last_result    =&gt; '0',
    last_run_time  =&gt; '1219328376.07815',
    last_todo      =&gt; '0',
    mtime          =&gt; '1191708862',
    seq            =&gt; '192',
    total_passes   =&gt; '6',
  }

=cut

sub tests {
    my $self = shift;
    if (@_) {
        $self-&gt;{tests} = shift;
        return $self;
    }
    my %tests = %{ $self-&gt;{tests} };
    my @tests = sort { $a-&gt;sequence &lt;=&gt; $b-&gt;sequence } values %tests;
    return wantarray ? @tests : \@tests;
}

=head3 C&lt;test&gt;

 my $test = $result-&gt;test('t/customer/create.t');

Returns an individual C&lt;App::Prove::State::Result::Test&gt; instance for the
given test name (usually the filename).  Will return a new
C&lt;App::Prove::State::Result::Test&gt; 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-&gt;{tests} ||= {};
    if ( my $test = $tests-&gt;{$name} ) {
        return $test;
    }
    else {
        my $test = $self-&gt;test_class-&gt;new( { name =&gt; $name } );
        $self-&gt;{tests}-&gt;{$name} = $test;
        return $test;
    }
}

=head3 C&lt;test_names&gt;

Returns an list of test names, sorted by run order.

=cut

sub test_names {
    my $self = shift;
    return map { $_-&gt;name } $self-&gt;tests;
}

=head3 C&lt;remove&gt;

 $result-&gt;remove($test_name);            # remove the test
 my $test = $result-&gt;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-&gt;{tests}-&gt;{$name};
    return $self;
}

=head3 C&lt;num_tests&gt;

Returns the number of tests for a given test suite result.

=cut

sub num_tests { keys %{ shift-&gt;{tests} } }

=head3 C&lt;raw&gt;

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-&gt;tests ) {
        $tests{ $test-&gt;name } = $test-&gt;raw;
    }
    $raw{tests} = \%tests;
    return \%raw;
}

1;
</pre></body></html>