File Coverage

File:blib/lib/App/Test/Generator/Planner/Fixture.pm
Coverage:100.0%

linestmtbrancondsubtimecode
1package App::Test::Generator::Planner::Fixture;
2
3
8
8
8
127625
8
99
use strict;
4
8
8
8
12
5
141
use warnings;
5
8
8
8
13
7
184
use Carp    qw(croak);
6
8
8
8
388
3310
870
use Readonly;
7
8# --------------------------------------------------
9# Isolation mode that triggers shared fixture reuse
10# --------------------------------------------------
11Readonly my $MODE_SHARED_FIXTURE => 'shared_fixture';
12
13# --------------------------------------------------
14# Fixture mode labels written to the plan output
15# --------------------------------------------------
16Readonly my $FIXTURE_SHARED       => 'shared';
17Readonly my $FIXTURE_NEW_PER_TEST => 'new_per_test';
18
19our $VERSION = '0.36';
20
21 - 59
=head1 VERSION

Version 0.36

=head1 DESCRIPTION

Plans fixture setup strategy for each method under test, based on the
isolation requirements provided by
L<App::Test::Generator::Planner::Isolation>. Methods that share state
are assigned a shared fixture; all others get a fresh fixture per test.

=head2 new

Construct a new Fixture planner.

    my $planner = App::Test::Generator::Planner::Fixture->new;

=head3 Arguments

None.

=head3 Returns

A blessed hashref.

=head3 API specification

=head4 input

    {}

=head4 output

    {
        type => OBJECT,
        isa  => 'App::Test::Generator::Planner::Fixture',
    }

=cut
60
61sub new {
62
23
181686
        my $class = $_[0];
63
23
24
        return bless {}, $class;
64}
65
66 - 122
=head2 plan

Produce a fixture plan for each method based on its isolation mode.
Methods with isolation mode C<shared_fixture> are assigned a shared
fixture; all other methods get a fresh fixture per test.

    my $planner   = App::Test::Generator::Planner::Fixture->new;
    my $fixture   = $planner->plan($schema, $isolation);

    for my $method (keys %{$fixture}) {
        printf "%s: %s\n", $method, $fixture->{$method}{mode};
    }

=head3 Arguments

=over 4

=item * C<$schema>

A hashref representing the module schema. Currently unused but
reserved for future fixture customisation based on schema metadata.

=item * C<$isolation>

A hashref mapping method names to isolation mode strings as produced
by L<App::Test::Generator::Planner::Isolation>.

=back

=head3 Returns

A hashref mapping method names to fixture plan hashrefs, each with a
C<mode> key set to either C<shared> or C<new_per_test>.

=head3 API specification

=head4 input

    {
        self      => { type => OBJECT,  isa     => 'App::Test::Generator::Planner::Fixture' },
        schema    => { type => HASHREF },
        isolation => { type => HASHREF },
    }

=head4 output

    {
        type  => HASHREF,
        keys  => {
            '*' => {
                type => HASHREF,
                keys => { mode => { type => SCALAR } },
            },
        },
    }

=cut
123
124sub plan {
125
26
2862
        my ($self, $schema, $isolation) = @_;
126
127        # Validate that isolation is a hashref before iterating
128
26
55
        croak 'isolation must be a hashref' unless ref($isolation) eq 'HASH';
129
130
20
11
        my %fixture;
131
132        # --------------------------------------------------
133        # Assign fixture mode per method based on isolation.
134        # Shared fixture mode reuses one object across tests
135        # for methods that share state; all others get a
136        # fresh object constructed per test case.
137        # --------------------------------------------------
138
20
20
17
22
        for my $method (keys %{$isolation}) {
139
20
22
                my $mode = $isolation->{$method} eq $MODE_SHARED_FIXTURE
140                        ? $FIXTURE_SHARED
141                        : $FIXTURE_NEW_PER_TEST;
142
143
20
89
                $fixture{$method} = { mode => $mode };
144        }
145
146
20
21
        return \%fixture;
147}
148
1491;