App-Test-Generator
view release on metacpan or search on metacpan
$a + ($b // 0), where $b never sits next to an operator itself);
such parameters fell back to type 'string', so fuzz-generated
non-numeric inputs caused generated tests to fail against code
that legitimately dies on non-numeric input. An explicit
looks_like_number($param) call in the source is now treated as a
direct numeric-type assertion, checked before the existing
arithmetic-operator and comparison heuristics.
- Fix _compile_signature_isolated()'s "fast path" Safe compartment,
tried before falling back to the subprocess unconditionally;
Type::Params/Types::Common pull in XS modules and Safe cannot host
XS/dynamic loading, so the compartment never succeeded for any real
signature_for() declaration and was dead code giving a false
impression of sandboxing. Removed; the subprocess path (gated on
allow_signature_exec => 1) is now the only path.
- Fix Generator.pm splicing module/function/transform/field names
unescaped into generated test source; added _assert_identifier()
and applied it before every such splice point so a name that is
not identifier-shaped now croaks instead of producing a test file
with injected code.
- Fix extract-schemas2 calling Planner->new without the required
package argument, crashing on every invocation; package is now
passed through from the extracted schema.
- Fix Template.pm _dedup_cases() always being a no-op: a return
inside the eval{} block returned from the eval, not from
_dedup_cases, so the deduplicated result was discarded and the
unduplicated $cases was always returned to the caller.
- Fix SchemaExtractor _detect_dependencies() relationship detection
losing pos() state on a shared $code string across nested global
matches; affected loops now operate on independent copies/resets.
- Fix SchemaExtractor numeric boundary-value hints double-counting
values already present from a previous hint pass; boundary values
are now added through a seen-value set, so re-running hint
generation on the same schema no longer duplicates values.
- Fix SchemaExtractor _detect_external_object_dependency() not
resetting pos($method_body) before its global match, so a prior
match elsewhere on the same string could cause this detector to
start scanning mid-string and miss leading dependencies; pos() is
now explicitly reset to 0 first.
- Fix CoverageGuidedFuzzer calling target_sub with no time bound, so
a target that hangs (e.g. on an unexpected infinite-loop input)
hung the whole fuzz run; calls are now wrapped in alarm()-based
timeout (default 5s, configurable via timeout => N, 0 disables).
- Fix LCSAJ.pm's CFG builder connecting every branch point only to a
newly-created true-block successor, leaving the false-arm block
disconnected from the frontier and silently dropped as an empty
leaf with no lines or edges; both true and false successors are
now wired into the frontier so subsequent statements are recorded
against both arms.
- Fix Mutator generate_mutants() never calling each mutation
strategy's applies_to() pre-filter before mutate(), and never
populating the context/line_content fields on the Mutant objects
it constructs; both are now wired through.
- Fix Analyzer::SideEffect.pm and Analyzer::Complexity.pm counting
IO/exec keywords, branch/logic/exception keywords, and the
literal ? character when they merely appeared inside a string
literal or comment (e.g. "Are you sure?" or a # comment containing
"die"); source is now stripped of string and comment content
before these keyword/operator counts are taken.
- Fix Analyzer::Return.pm's \$self(?!->) returns_self pattern
matching the \$self prefix of any longer variable name (e.g.
\$self_backup, \$selfish); added a \b word boundary. Also fixed
all three return-pattern matches running as a single non-/g match,
so a method with several qualifying return statements only ever
contributed one evidence entry instead of one per occurrence.
- Fix Mutation::BooleanNegation and Mutation::ReturnUndef mutating
only the first PPI token of a multi-token return expression (e.g.
$self->{value}), since $ret->schild(1) captures just the leading
Symbol token of a chained/dereferencing expression; this produced
broken mutants like 'return !($self)->{value};' and
'return undef->{value};' that die at runtime rather than testing
the intended boolean/undef substitution. Both now resolve the
full expression span (up to a trailing postfix conditional/loop
modifier or the statement terminator) and wrap/replace it as a
whole.
- Fix SchemaExtractor _analyze_relationships() extracting parameter
names with a hardcoded my (...) = @_ regex only, so shift-style
(my $x = shift) and modern-signature (sub foo($self, $x)) methods
never had their parameter relationships (mutually-exclusive,
required-group, dependency, etc.) analysed; parameter extraction
now reuses _extract_parameters_from_signature(), which already
supports all four parameter-declaration styles.
- Fix Analyzer::ReturnMeta.pm's stability bonus for boolean returns
being undocumented in POD: since stability_score starts at 100 and
is clamped to [0, 100], the bonus is a no-op unless an earlier
penalty already reduced the score, which POD readers had no way of
knowing. Documented the no-op-in-the-common-case behaviour.
- Fix Planner::Mock.pm plan() silently dropping the capture_io mock
for any method that is both calls_external and performs_io, since
the if/elsif gave mock_system precedence; such a method now gets
an arrayref of both mock strategies instead of losing one.
- Fix CoverageGuidedFuzzer.pm _run_with_cover() walking the full
Devel::Cover state twice per fuzz iteration (once for "before",
once for "after"); coverage state only grows, so this iteration's
"before" is now the cached "after" snapshot from the previous
iteration, halving the per-iteration Devel::Cover walk count.
- Fix CoverageGuidedFuzzer.pm _validate_value() matching a schema-
supplied 'matches' regex against fuzzer-generated input with no
bound on catastrophic backtracking; the match is now wrapped in
the same alarm()-based timeout already used to bound target_sub
calls, and a timeout is treated as a non-match.
- Fix SchemaExtractor.pm's TODO POD section claiming union-type
parsing (e.g. scalar | scalarref) in =head4 Input specs was
unimplemented; _map_formal_input_type already handles it. Narrowed
the TODO to the part that is genuinely still unimplemented (the
enum/memberof constraint synonym).
- Fix TestStrategy.pm's getset-accessor branch picking an arbitrary,
hash-order-dependent input parameter when more than one candidate
was present; candidates are now sorted by their schema position
field first, making the choice deterministic.
- Fix LCSAJ::Coverage.pm's custom "Cannot read $file: $!" / "Cannot
write coverage output to $out_file: $!" croak messages being
unreachable dead code under "use autodie qw(:all)" (autodie's
open() never returns false, so "open(...) or croak(...)" never
fires); autodie is now disabled locally for these two open calls
so the documented custom messages are actually produced on failure.
[Enhancements]
- Add cross-module end-to-end subtests to t/integration.t:
Planner::build_plan()'s full five-subsystem composition (verifying
the documented TestStrategy/Mock/Isolation/Fixture/Grouping
responsibility split with real side-effect/dependency metadata,
( run in 0.898 second using v1.01-cache-2.11-cpan-804bf51f3ce )