NAME
App::Test::Generator::Mutation::BooleanNegation - Negate boolean return expressions to expose missing assertion coverage
VERSION
Version 0.40
METHODS
applies_to
Return true if the given document contains at least one return statement this mutation strategy could mutate. Used by App::Test::Generator::Mutator to pre-filter strategies before calling mutate, so a document with nothing to mutate skips the walk entirely.
my $applies = $mutation->applies_to($doc);
Arguments
$docA PPI::Document object to inspect.
Returns
True if the document contains a return statement (PPI::Statement::Break whose first token is return), false otherwise.
API specification
input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Mutation::BooleanNegation' },
doc => { type => OBJECT, isa => 'PPI::Document' },
}
output
{ type => SCALAR }
mutate
Walk a PPI document and generate one mutant for each return statement whose expression can be negated. For example, return $ok becomes return !($ok).
my $mutation = App::Test::Generator::Mutation::BooleanNegation->new;
my $doc = PPI::Document->new(\$source);
my @mutants = $mutation->mutate($doc);
for my $m (@mutants) {
print $m->id, ': ', $m->description, "\n";
}
Arguments
$selfAn instance of
App::Test::Generator::Mutation::BooleanNegation.$docA PPI::Document object representing the parsed source to mutate. The document is not modified by this method.
Returns
A list of App::Test::Generator::Mutant objects, one per qualifying return statement found in the document. Returns an empty list if no return statements with expressions are found.
Each mutant carries a transform closure that when called with a fresh PPI::Document copy will wrap the targeted return expression in !( ), negating its boolean value.
Notes
Mutant IDs include both line and column number to ensure uniqueness when multiple return statements appear on different lines of the same source file.
Only return statements that have an expression child (i.e. not bare return; statements) are mutated.
Each mutant's optional context field is set to conditional if the return statement sits inside (or is itself the keyword of) an if/unless/while/until compound statement, or statement otherwise; its line_content field holds the raw source text of the mutated line. Both are consumed by App::Test::Generator::Mutator's fast-mode dedup.
API specification
input
{
self => {
type => OBJECT,
isa => 'App::Test::Generator::Mutation::BooleanNegation',
},
doc => {
type => OBJECT,
isa => 'PPI::Document',
},
}
output
{
type => ARRAYREF,
elements => {
type => OBJECT,
isa => 'App::Test::Generator::Mutant',
},
}
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
LICENCE AND COPYRIGHT
Copyright 2026 Nigel Horne.
Usage is subject to licence terms.
The licence terms of this software are as follows:
Personal single user, single computer use: GPL2
All other users (including Commercial, Charity, Educational, Government) must apply in writing for a licence for use from Nigel Horne at the above e-mail.