| File: | blib/lib/App/Test/Generator/Planner/Grouping.pm |
| Coverage: | 100.0% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package App::Test::Generator::Planner::Grouping; | |||||
| 2 | ||||||
| 3 | 8 8 8 | 64925 8 97 | use strict; | |||
| 4 | 8 8 8 | 13 6 136 | use warnings; | |||
| 5 | 8 8 8 | 14 6 134 | use Carp qw(croak); | |||
| 6 | 8 8 8 | 204 1684 1027 | use Readonly; | |||
| 7 | ||||||
| 8 | # -------------------------------------------------- | |||||
| 9 | # Purity level strings from Analyzer::SideEffect | |||||
| 10 | # -------------------------------------------------- | |||||
| 11 | Readonly my $PURITY_PURE => 'pure'; | |||||
| 12 | Readonly my $PURITY_SELF_MUTATING => 'self_mutating'; | |||||
| 13 | ||||||
| 14 | # -------------------------------------------------- | |||||
| 15 | # Group keys in the output plan. | |||||
| 16 | # Note: self_mutating maps to 'mutating' in the | |||||
| 17 | # group key to keep the output API concise. | |||||
| 18 | # -------------------------------------------------- | |||||
| 19 | Readonly my $GROUP_PURE => 'pure'; | |||||
| 20 | Readonly my $GROUP_MUTATING => 'mutating'; | |||||
| 21 | Readonly my $GROUP_IMPURE => 'impure'; | |||||
| 22 | ||||||
| 23 | our $VERSION = '0.36'; | |||||
| 24 | ||||||
| 25 - 62 | =head1 VERSION
Version 0.36
=head1 DESCRIPTION
Groups methods by their purity level for more efficient test file
organisation. Pure methods can share setup; mutating methods need
per-test objects; impure methods need full isolation blocks.
=head2 new
Construct a new Grouping planner.
my $planner = App::Test::Generator::Planner::Grouping->new;
=head3 Arguments
None.
=head3 Returns
A blessed hashref.
=head3 API specification
=head4 input
{}
=head4 output
{
type => OBJECT,
isa => 'App::Test::Generator::Planner::Grouping',
}
=cut | |||||
| 63 | ||||||
| 64 | sub new { | |||||
| 65 | 24 | 113313 | my $class = $_[0]; | |||
| 66 | 24 | 30 | return bless {}, $class; | |||
| 67 | } | |||||
| 68 | ||||||
| 69 - 122 | =head2 plan
Group all methods in the schema by their purity level.
my $planner = App::Test::Generator::Planner::Grouping->new;
my $groups = $planner->plan($schema);
printf "Pure methods: %s\n", join(', ', @{ $groups->{pure} });
printf "Mutating methods:%s\n", join(', ', @{ $groups->{mutating} });
printf "Impure methods: %s\n", join(', ', @{ $groups->{impure} });
=head3 Arguments
=over 4
=item * C<$schema>
A hashref of method schemas each optionally containing a C<_analysis>
key with a C<side_effects> sub-key as produced by
L<App::Test::Generator::Analyzer::SideEffect>.
=back
=head3 Returns
A hashref with three keys â C<pure>, C<mutating>, and C<impure> â
each containing an arrayref of method names assigned to that group.
Methods without purity metadata are placed in C<impure> by default.
Note: the purity level C<self_mutating> from
L<App::Test::Generator::Analyzer::SideEffect> is mapped to the
C<mutating> group key in this output.
=head3 API specification
=head4 input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Planner::Grouping' },
schema => { type => HASHREF },
}
=head4 output
{
type => HASHREF,
keys => {
pure => { type => ARRAYREF },
mutating => { type => ARRAYREF },
impure => { type => ARRAYREF },
},
}
=cut | |||||
| 123 | ||||||
| 124 | sub plan { | |||||
| 125 | 22 | 1315 | my ($self, $schema) = @_; | |||
| 126 | ||||||
| 127 | # Validate that schema is a hashref before iterating | |||||
| 128 | 22 | 49 | croak 'schema must be a hashref' | |||
| 129 | unless ref($schema) eq 'HASH'; | |||||
| 130 | ||||||
| 131 | # Initialise all three groups so the output always | |||||
| 132 | # has all three keys even if some groups are empty | |||||
| 133 | 16 | 28 | my %groups = ( | |||
| 134 | $GROUP_PURE => [], | |||||
| 135 | $GROUP_MUTATING => [], | |||||
| 136 | $GROUP_IMPURE => [], | |||||
| 137 | ); | |||||
| 138 | ||||||
| 139 | 16 16 | 87 19 | for my $method (keys %{$schema}) { | |||
| 140 | # Default to empty string if purity_level is absent â | |||||
| 141 | # missing metadata falls through to the impure group | |||||
| 142 | 22 | 29 | my $level = $schema->{$method}{_analysis}{side_effects}{purity_level} // ''; | |||
| 143 | ||||||
| 144 | # Map purity level to group key â self_mutating becomes | |||||
| 145 | # 'mutating' to keep the output API concise | |||||
| 146 | 22 | 17 | my $group = | |||
| 147 | $level eq $PURITY_PURE ? $GROUP_PURE : | |||||
| 148 | $level eq $PURITY_SELF_MUTATING ? $GROUP_MUTATING : | |||||
| 149 | $GROUP_IMPURE; | |||||
| 150 | ||||||
| 151 | 22 22 | 90 27 | push @{ $groups{$group} }, $method; | |||
| 152 | } | |||||
| 153 | ||||||
| 154 | 16 | 18 | return \%groups; | |||
| 155 | } | |||||
| 156 | ||||||
| 157 | 1; | |||||