NAME
App::Test::Generator::SchemaExtractor - Extract test schemas from Perl modules
VERSION
Version 0.23
SYNOPSIS
use App::Test::Generator::SchemaExtractor;
my $extractor = App::Test::Generator::SchemaExtractor->new(
input_file => 'lib/MyModule.pm',
output_dir => 'schemas/',
verbose => 1,
);
my $schemas = $extractor->extract_all();
DESCRIPTION
App::Test::Generator::SchemaExtractor analyzes Perl modules and generates structured YAML schema files suitable for automated test generation by App::Test::Generator. This module employs static analysis techniques to infer parameter types, constraints, and method behaviors directly from your source code.
Analysis Methods
The extractor combines multiple analysis approaches for comprehensive schema generation:
POD Documentation Analysis
Parses embedded documentation to extract: - Parameter names, types, and descriptions from =head2 sections - Method signatures with positional parameters - Return value specifications from "Returns:" sections - Constraints (ranges, patterns, required/optional status) - Semantic type detection (email, URL, filename)
Code Pattern Detection
Analyzes source code using PPI to identify: - Method signatures and parameter extraction patterns - Type validation (ref(), isa(), blessed()) - Constraint patterns (length checks, numeric comparisons, regex matches) - Return statement analysis and value type inference - Object instantiation requirements and accessor methods
Signature Analysis
Examines method declarations for: - Parameter names and positional information - Instance vs. class method detection - Method modifiers (Moose-style before/after/around) - Various parameter declaration styles (shift, @_ assignment)
Heuristic Inference
Applies Perl-specific domain knowledge: - Boolean return detection from method names (is_*, has_*, can_*) - Common Perl idioms and coding patterns - Context awareness (scalar vs list, wantarray usage) - Object-oriented patterns (constructors, accessors, chaining)
Generated Schema Structure
The extracted schemas follow this YAML structure:
function: method_name
module: Package::Name
input:
param1:
type: string
min: 3
max: 50
optional: 0
position: 0
param2:
type: integer
min: 0
max: 100
optional: 1
position: 1
output:
type: boolean
value: 1
new: Package::Name # if object instantiation required
config:
test_empty: 1
test_nuls: 0
test_undef: 0
test_non_ascii: 0
Advanced Detection Capabilities
Accessor Method Detection
Automatically identifies getter, setter, and combined accessor methods by analyzing common patterns like
return $self->{field}and$self->{field} = $value.Boolean Return Inference
Detects boolean-returning methods through multiple signals: - Method name patterns (is_*, has_*, can_*) - Return patterns (consistent 1/0 returns) - POD descriptions ("returns true on success") - Ternary operators with boolean results
Context Awareness
Identifies methods that use
wantarrayand can return different values in scalar vs list context.Object Lifecycle Management
Detects instance methods requiring object instantiation and automatically adds the
newfield to schemas.Enhanced Object Detection
The extractor includes sophisticated object detection capabilities that go beyond simple instance method identification:
Factory Method Recognition
Automatically identifies methods that create and return object instances, such as methods named
create_*,make_*,build_*, orget_*. Factory methods are correctly classified as class methods that don't require pre-existing objects for testing.Singleton Pattern Detection
Recognizes singleton patterns through multiple signals: method names like
instanceorget_instance, static variables holding instance references, lazy initialization patterns ($instance ||= new()), and consistent return of the same instance variable.Constructor Parameter Analysis
Examines
newmethods to determine required and optional parameters, validation requirements, and default values. This enables test generators to provide appropriate constructor arguments when object instantiation is needed.Inheritance Relationship Handling
Detects parent classes through
use parent,use base, and@ISAdeclarations. Identifies when methods useSUPER::calls and determines whether the current class or a parent class constructor should be used for object instantiation.External Object Dependency Detection
Identifies when methods create or depend on objects from other classes, enabling proper test setup with mock objects or real dependencies.
These enhancements ensure that generated test schemas accurately reflect the object-oriented structure of the code, leading to more meaningful and effective test generation.
Confidence Scoring
Each generated schema includes detailed confidence assessments:
High Confidence
Multiple independent analysis sources converge on consistent, well-constrained parameters with explicit validation logic and comprehensive documentation.
Medium Confidence
Reasonable evidence from code patterns or partial documentation, but may lack comprehensive constraints or have some ambiguities.
Low Confidence
Minimal evidence - primarily based on naming conventions, default assumptions, or single-source analysis.
Very Low Confidence
Barely any detectable signals - schema should be thoroughly reviewed before use in test generation.
Use Cases
Automated Test Generation
Generate comprehensive test suites with App::Test::Generator using extracted schemas as input. The schemas provide the necessary structure for generating both positive and negative test cases.
API Documentation Generation
Supplement existing documentation with automatically inferred interface specifications, parameter requirements, and return types.
Code Quality Assessment
Identify methods with poor documentation, inconsistent parameter handling, or unclear interfaces that may benefit from refactoring.
Refactoring Assistance
Detect method dependencies, object instantiation requirements, and parameter usage patterns to inform refactoring decisions.
Legacy Code Analysis
Quickly understand the interface contracts of legacy Perl codebases without extensive manual code reading.
Integration with Testing Ecosystem
The generated schemas are specifically designed to work with the App::Test::Generator ecosystem:
# Extract schemas from your module
my $extractor = App::Test::Generator::SchemaExtractor->new(...);
my $schemas = $extractor->extract_all();
# Use with test generator (typically as separate steps)
# fuzz-harness-generator -r schemas/method_name.yml
Limitations and Considerations
Dynamic Code Patterns
Highly dynamic code (string evals, AUTOLOAD, symbolic references) may not be fully detected by static analysis.
Complex Validation Logic
Sophisticated validation involving multiple parameters or external dependencies may require manual schema refinement.
Confidence Heuristics
Confidence scores are based on heuristics and should be reviewed by developers familiar with the codebase.
Perl Idiom Recognition
Some Perl-specific idioms may require custom pattern recognition beyond the built-in detectors.
Documentation Dependency
Analysis quality improves significantly with comprehensive POD documentation following consistent patterns.
Best Practices for Optimal Results
Comprehensive POD Documentation
Write detailed POD with explicit parameter documentation using consistent patterns like
$param - type (constraints), description.Consistent Coding Patterns
Use consistent parameter validation patterns and method signatures throughout your codebase.
Schema Review Process
Review and refine automatically generated schemas, particularly those with low confidence scores.
Descriptive Naming
Use descriptive method and parameter names that clearly indicate purpose and expected types.
Progressive Enhancement
Start with automatically generated schemas and progressively refine them based on test results and code understanding.
The module is particularly valuable for large codebases where manual schema creation would be prohibitively time-consuming, and for maintaining test coverage as code evolves through continuous integration pipelines.
Advanced Type Detection
The schema extractor includes enhanced type detection capabilities that identify specialized Perl types beyond basic strings and integers. DateTime and Time::Piece objects are detected through isa() checks and method call patterns, while date strings (ISO 8601, YYYY-MM-DD) and UNIX timestamps are recognized through regex validation and numeric range checks. File handles and file paths are identified via I/O operations and file test operators, coderefs are detected through ref() checks and invocation patterns, and enum-like parameters are extracted from validation code including regex patterns (/^(a|b|c)$/), hash lookups, grep statements, and if/elsif chains. These detected types are preserved in the generated YAML schemas with appropriate semantic annotations, enabling test generators to create more accurate and meaningful test cases.
Example Advanced Type Schema
For a method like:
sub process_event {
my ($self, $timestamp, $status, $callback) = @_;
croak unless $timestamp > 1000000000;
croak unless $status =~ /^(active|pending|complete)$/;
croak unless ref($callback) eq 'CODE';
$callback->($timestamp, $status);
}
The extractor generates:
---
function: process_event
module: MyModule
input:
timestamp:
type: integer
# min: 0
# max: 2147483647
position: 0
_note: Unix timestamp
semantic: unix_timestamp
status:
type: string
enum:
- active
- pending
- complete
position: 1
_note: 'Must be one of: active, pending, complete'
callback:
type: coderef
position: 2
_note: 'CODE reference - provide sub { } in tests'
RELATIONSHIP DETECTION
The schema extractor detects relationships and dependencies between parameters, enabling more sophisticated validation and test generation.
Relationship Types
mutually_exclusive
Parameters that cannot be used together.
die if $file && $content; # Can't specify bothGenerated schema:
relationships: - type: mutually_exclusive params: [file, content] description: Cannot specify both file and contentrequired_group
At least one parameter from the group must be specified (OR logic).
die unless $id || $name; # Must provide oneGenerated schema:
relationships: - type: required_group params: [id, name] logic: or description: Must specify either id or nameconditional_requirement
If one parameter is specified, another becomes required (IF-THEN logic).
die if $async && !$callback; # async requires callbackGenerated schema:
relationships: - type: conditional_requirement if: async then_required: callback description: When async is specified, callback is requireddependency
One parameter depends on another being present.
die "Port requires host" if $port && !$host;Generated schema:
relationships: - type: dependency param: port requires: host description: port requires host to be specifiedvalue_constraint
Specific value requirements between parameters.
die if $ssl && $port != 443; # ssl requires port 443Generated schema:
relationships: - type: value_constraint if: ssl then: port operator: == value: 443 description: When ssl is specified, port must equal 443value_conditional
Parameter required when another has a specific value.
die if $mode eq 'secure' && !$key;Generated schema:
relationships: - type: value_conditional if: mode equals: secure then_required: key description: When mode equals 'secure', key is required
Default Value Extraction
The extractor comprehensively extracts default values from both code and POD documentation:
Code Pattern Recognition
Extracts defaults from multiple Perl idioms:
Logical OR operator:
$param = $param || 'default'Defined-or operator:
$param //= 'default'Ternary operator:
$param = defined $param ? $param : 'default'Unless conditional:
$param = 'default' unless defined $paramChained defaults:
$param = $param || $self-{default} || 'fallback'>Multi-line patterns:
$param = {} unless $param
POD Pattern Recognition
Extracts defaults from documentation:
Standard format:
Default: 'value'Alternative format:
Defaults to: 'value'Inline format:
Optional, default: 'value'Parameter lists:
$param - type, default 'value'
Value Processing
Properly handles:
String literals with quotes and escape sequences
Numeric values (integers and floats)
Boolean values (true/false converted to 1/0)
Empty data structures ([] and {})
Special values (undef, __PACKAGE__)
Complex expressions (preserved as-is when unevaluatable)
Quote operators (q{}, qq{}, qw{})
Type Inference
When a parameter has a default value but no explicit type annotation, the type is automatically inferred from the default:
$options = {} # inferred as hashref
$items = [] # inferred as arrayref
$count = 42 # inferred as integer
$ratio = 3.14 # inferred as number
$enabled = 1 # inferred as boolean
Context-Aware Return Analysis
The extractor provides comprehensive analysis of method return behavior, including context sensitivity, error handling conventions, and method chaining patterns.
List vs Scalar Context Detection
Automatically detects methods that return different values based on calling context:
sub get_items {
my ($self) = @_;
return wantarray ? @items : scalar(@items);
}
Detection captures:
context_awareflag - Method uses wantarraylist_context- Type returned in list context (e.g., 'array')scalar_context- Type returned in scalar context (e.g., 'integer')
Recognizes both ternary operator patterns and conditional return patterns.
Void Context Methods
Identifies methods that don't return meaningful values:
Setters (
set_*methods)Mutators (
add_*, remove_*, delete_*, clear_*, reset_*, update_*)Loggers (
log, debug, warn, error, info)Methods with only empty returns
Example:
sub set_name {
my ($self, $name) = @_;
$self->{name} = $name;
return; # Void context
}
Sets void_context flag and type => 'void'.
Method Chaining Detection
Identifies chainable methods that return $self for fluent interfaces:
sub set_width {
my ($self, $width) = @_;
$self->{width} = $width;
return $self; # Chainable
}
Detection provides:
chainableflag - Method supports chainingreturns_self- Returns invocant for chainingclass- The class name being returned
Also detects chaining documentation in POD (keywords: "chainable", "fluent interface", "returns self", "method chaining").
Error Return Conventions
Analyzes how methods signal errors:
Pattern Detection:
undef_on_error- Explicitreturn undef if/unless conditionimplicit_undef- Barereturn if/unless conditionempty_list-return ()for list context errorszero_on_error- Returns 0/false for boolean error indicationexception_handling- Uses eval blocks with error checking
Example Analysis:
sub fetch_user {
my ($self, $id) = @_;
return undef unless $id; # undef_on_error
return undef if $id < 0; # undef_on_error
return $self->{users}{$id};
}
Results in:
error_return: 'undef'
success_failure_pattern: 1
error_handling: {
undef_on_error: ['$id', '$id < 0']
}
Success/Failure Pattern:
Methods that return different types for success vs. failure are flagged with success_failure_pattern. Common patterns:
Returns value on success, undef on failure
Returns true on success, false on failure
Returns data on success, empty list on failure
Success Indicator Detection
Methods that always return true (typically for side effects):
sub update_status {
my ($self, $status) = @_;
$self->{status} = $status;
return 1; # Success indicator
}
Sets success_indicator flag when method consistently returns 1.
Schema Output
Enhanced return analysis adds these fields to method schemas:
output:
type: boolean # Inferred return type
context_aware: 1 # Uses wantarray
list_context:
type: array
scalar_context:
type: integer
chainable: 1 # Returns $self
returns_self: 1
void_context: 1 # No meaningful return
success_indicator: 1 # Always returns true
error_return: undef # How errors are signaled
success_failure_pattern: 1 # Mixed return types
error_handling: # Detailed error patterns
undef_on_error: [...]
exception_handling: 1
This comprehensive analysis enables:
Better test generation (testing both contexts, error paths)
Documentation generation (clear error conventions)
API design validation (consistent error handling)
Contract specification (precise return behavior)
Example
For a method like:
sub connect {
my ($self, $host, $port, $ssl, $file, $content) = @_;
die if $file && $content; # mutually exclusive
die unless $host || $file; # required group
die "Port requires host" if $port && !$host; # dependency
die if $ssl && $port != 443; # value constraint
# ... connection logic
}
The extractor generates:
relationships:
- type: mutually_exclusive
params: [file, content]
description: Cannot specify both file and content
- type: required_group
params: [host, file]
logic: or
description: Must specify either host or file
- type: dependency
param: port
requires: host
description: port requires host to be specified
- type: value_constraint
if: ssl
then: port
operator: ==
value: 443
description: When ssl is specified, port must equal 443
MODERN PERL FEATURES
This module adds support for:
Subroutine Signatures (Perl 5.20+)
sub connect($host, $port = 3306, %options) {
...
}
Extracts: required params, optional params with defaults, slurpy params
Type Constraints (Perl 5.36+)
sub calculate($x :Int, $y :Num) {
...
}
Recognizes: Int, Num, Str, Bool, ArrayRef, HashRef, custom classes
Subroutine Attributes
sub get_value :lvalue :Returns(Int) {
...
}
Detects: :lvalue, :method, :Returns(Type), custom attributes
Postfix Dereferencing (Perl 5.20+)
my @array = $arrayref->@*;
my %hash = $hashref->%*;
my @slice = $arrayref->@[1,3,5];
Tracks usage of modern dereferencing syntax
Field Declarations (Perl 5.38+)
field $host :param = 'localhost';
field $port :param(port_number) = 3306;
field $logger :param :isa(Log::Any);
Extracts fields and maps them to parameters
Modern Perl Features Support
The schema extractor supports modern Perl syntax introduced in versions 5.20, 5.36, and 5.38+.
Subroutine Signatures (Perl 5.20+)
Automatically extracts parameters from native Perl signatures:
use feature 'signatures';
sub connect($host, $port = 3306, $database = undef) {
...
}
Extracted schema includes:
Parameter positions
Optional vs required parameters
Default values from signature
Slurpy parameters (@array, %hash)
Example:
# Signature with defaults
sub process($file, %options) { ... }
# Extracts:
# $file: position 0, required
# %options: position 1, optional, slurpy hash
Type Constraints in Signatures (Perl 5.36+)
Recognizes type constraints in signature parameters:
sub calculate($x :Int, $y :Num, $name :Str = "result") {
return $x + $y;
}
Supported constraint types:
:Int, :Integer-> integer:Num, :Number-> number:Str, :String-> string:Bool, :Boolean-> boolean:ArrayRef, :Array-> arrayref:HashRef, :Hash-> hashref:ClassName-> object with isa constraint
Type constraints are combined with defaults when both are present.
Subroutine Attributes
Extracts and documents subroutine attributes:
sub get_value :lvalue {
my $self = shift;
return $self->{value};
}
sub calculate :Returns(Int) :method {
my ($self, $x, $y) = @_;
return $x + $y;
}
Recognized attributes stored in _attributes field:
:lvalue- Method can be assigned to:method- Explicitly marked as method:Returns(Type)- Declares return typeCustom attributes with values:
:MyAttr(value)
Postfix Dereferencing (Perl 5.20+)
Detects usage of postfix dereferencing syntax:
use feature 'postderef';
sub process_array {
my ($self, $arrayref) = @_;
my @array = $arrayref->@*; # Array dereference
my @slice = $arrayref->@[1,3,5]; # Array slice
return @array;
}
sub process_hash {
my ($self, $hashref) = @_;
my %hash = $hashref->%*; # Hash dereference
return keys %hash;
}
Tracked features stored in _modern_features:
array_deref- Uses->@*hash_deref- Uses->%*scalar_deref- Uses->$*code_deref- Uses->&*array_slice- Uses->@[...]hash_slice- Uses->%{...}
Field Declarations (Perl 5.38+)
Extracts field declarations from class syntax and maps them to method parameters:
use feature 'class';
class DatabaseConnection {
field $host :param = 'localhost';
field $port :param = 3306;
field $username :param(user);
field $password :param;
field $logger :param :isa(Log::Any);
method connect() {
# Fields available as instance variables
}
}
Field attributes:
:param- Field is a constructor parameter (uses field name):param(name)- Field maps to parameter with different name:isa(Class)- Type constraint for the fieldDefault values in field declarations
Extracted schema includes both field information in _fields and merged parameter information in input, allowing proper validation of class constructors.
Mixed Modern and Traditional Syntax
The extractor handles code that mixes modern and traditional syntax:
sub modern($x, $y = 5) {
# Modern signature with default
}
sub traditional {
my ($self, $x, $y) = @_;
$y //= 5; # Traditional default in code
# Both extract same parameter information
}
Priority order for parameter information:
- 1. Signature declarations (highest priority)
- 2. Field declarations (for class methods)
- 3. POD documentation
- 4. Code analysis (lowest priority)
This ensures that explicit declarations in signatures take precedence over inferred information from code analysis.
Backwards Compatibility
All modern Perl feature detection is optional and automatic:
Traditional
subdeclarations continue to workCode without modern features extracts parameters as before
Modern features are additive - they enhance rather than replace existing extraction
Schemas include
_sourcefield indicating where parameter info came from
_yamltest_hints
Each method schema returned by "extract_all" now optionally includes a _yamltest_hints key, which provides guidance for automated test generation based on the code analysis.
This is intended to help App::Test::Generator create meaningful tests, including boundary and invalid input cases, without manually specifying them.
The structure is a hashref with the following keys:
boundary_values
An arrayref of numeric values that represent boundaries detected from comparisons in the code. These are derived from literals in statements like
$x < 0or$y= 255>. The generator can use these to create boundary tests.Example:
_yamltest_hints: boundary_values: [0, 1, 100, 255]invalid_inputs
An arrayref of values that are likely to be rejected by the method, based on checks like
defined, empty strings, or numeric validations.Example:
_yamltest_hints: invalid_inputs: [undef, '', -1]equivalence_classes
An arrayref intended to capture detected equivalence classes or patterns among inputs. Currently this is empty by default, but future enhancements may populate it based on detected input groupings.
Example:
_yamltest_hints: equivalence_classes: []
Usage
When calling extract_all, each method schema will include _yamltest_hints if any hints were detected:
my $schemas = $extractor->extract_all;
my $hints = $schemas->{example_method}->{_yamltest_hints};
You can then feed these hints into automated test generators to produce negative tests, boundary tests, and parameter-specific test cases.
Notes
Hints are inferred heuristically from code and validation statements.
Not all inputs are guaranteed to be detected; the feature is additive and will never remove information from the schema.
Currently, equivalence classes are not populated, but the field exists for future extension.
Boundary and invalid input hints are deduplicated to avoid repeated test values.
Examples
Given a method like:
sub example {
my ($x) = @_;
die "negative" if $x < 0;
return unless defined($x);
return $x * 2;
}
After running:
my $extractor = App::Test::Generator::SchemaExtractor->new(
input_file => 'TestHints.pm',
output_dir => '/tmp',
quiet => 1,
);
my $schemas = $extractor->extract_all;
The schema for the method "example" will include:
$schemas->{example} = {
function => 'example',
_confidence => {
input => 'unknown',
output => 'unknown',
},
input => {
x => {
type => 'scalar',
optional => 0,
}
},
output => {
type => 'scalar',
},
_yamltest_hints => {
boundary_values => [0, 1],
invalid_inputs => [undef, -1],
equivalence_classes => [],
},
_notes => '...',
_analysis => {
input_confidence => 'low',
output_confidence => 'unknown',
confidence_factors => {
input => {...},
output => {...},
},
overall_confidence => 'low',
},
_fields => {},
_modern_features => {},
_attributes => {},
};
METHODS
new
Private methods are not included, unless include_private is used in new().
The extractor supports several configuration parameters:
my $extractor = App::Test::Generator::SchemaExtractor->new(
input_file => 'lib/MyModule.pm', # Required
output_dir => 'schemas/', # Default: 'schemas'
verbose => 1, # Default: 0
include_private => 1, # Default: 0
max_parameters => 50, # Default: 20
confidence_threshold => 0.7, # Default: 0.5
);
extract_all
Extract schemas for all methods in the module.
Returns a hashref of method_name => schema.
Pseudo Code
FOREACH method
DO
analyze the method
write a schema file for that method
END
_extract_package_name
Extract the package name from the document.
_find_methods
Find all subroutines/methods in the document.
Returns an arrayref of hashrefs with the structure: { name => $name, node => $ppi_node, body => $code_text }
_extract_pod_before
Extract POD documentation that appears before a subroutine.
_analyze_method
Analyze a method and generate its schema.
Combines POD analysis, code pattern analysis, and signature analysis.
_analyze_pod
Parse POD documentation to extract parameter information.
Looks for patterns like: $name - string (3-50 chars), username $age - integer, must be positive $email - string, matches /\@/
_analyze_output
Analyze return values from POD and code.
Looks for: - Returns: section in POD - return statements in code - Common patterns like "returns 1 on success"
_extract_defaults_from_pod
Extract default values from POD documentation.
Looks for patterns like: - Default: 'value' - Defaults to: value - Optional, default: value
_parse_constraints
Parse constraint strings like "3-50 chars" or "positive" or "1-100".
_analyze_code
Analyze code patterns to infer parameter types and constraints.
Looks for common validation patterns: - defined checks - ref() checks - regex matches - length checks - numeric comparisons
_analyze_advanced_types
Enhanced type detection for DateTime, file handles, coderefs, and enums. This adds semantic type information that can guide test generation.
_detect_datetime_type
Detect DateTime objects and date/time string parameters.
_detect_filehandle_type
Detect file handle parameters and file path strings.
_detect_coderef_type
Detect coderef/callback parameters.
_detect_enum_type
Detect enum-like parameters with fixed set of valid values.
_analyze_signature
Analyze method signature to extract parameter names.
_merge_parameter_analyses
Merge parameter information from multiple sources.
Priority: POD > Code > Signature
_calculate_confidence
Calculate confidence score for parameter analysis.
Returns: 'high', 'medium', 'low'
_generate_notes
Generate helpful notes about the analysis.
_analyze_relationships
Analyze relationships and dependencies between parameters.
Detects: - Mutually exclusive parameters (can't use both) - Required parameter groups (must use one of) - Conditional requirements (if X then Y) - Parameter dependencies (X requires Y) - Value-based constraints (X=5 requires Y)
_deduplicate_relationships
Remove duplicate relationship entries.
_detect_mutually_exclusive
Detect parameters that cannot be used together.
Patterns: die if $file && $content croak "Cannot specify both" if $x && $y die unless !($a && $b)
_detect_required_groups
Detect parameter groups where at least one must be specified (OR logic).
Patterns: die unless $id || $name croak "Must specify either X or Y" unless $x || $y
_detect_conditional_requirements
Detect conditional requirements (IF-THEN logic).
Patterns: die if $async && !$callback croak "X requires Y" if $x && !$y
_detect_dependencies
Detect simple parameter dependencies (X requires Y to exist).
Patterns: die 'Port requires host' if $port && !$host
_detect_value_constraints
Detect value-based constraints between parameters.
Patterns: die if $ssl && $port != 443 croak "Invalid combination" if $mode eq 'secure' && !$key
_write_schema
Write a schema to a YAML file.
_generate_schema_comments
Generate helpful comments at the end of the YAML file.
_serialize_parameter_for_yaml
Convert parameter hash to YAML-serializable format with proper type handling.
_needs_object_instantiation
Enhanced object detection that: - Detects factory methods that return instances - Recognizes singleton patterns - Identifies when constructor needs specific parameters - Handles inheritance (when parent class new() is needed) - Detects both instance methods and class methods that require objects
Returns: - undef if no object needed - package name if object instantiation is needed - hashref with constructor details if specific parameters are needed
_detect_factory_method
Detect factory methods that create and return instances.
Patterns: - Returns blessed references - Returns objects created with ->new() - Method names like create_*, make_*, build_* - Returns $self->new(...) or Class->new(...)
_detect_singleton_pattern
Detect singleton patterns: - Class methods that return $instance or $_instance - Static variable holding instance - Method names like instance(), get_instance()
_detect_instance_method
Detect if a method is an instance method that needs an object.
Enhanced detection with multiple patterns.
_check_inheritance_for_constructor
Check if inheritance affects which constructor should be used.
Patterns: - use parent/base statements - @ISA array - SUPER::new calls - parent class methods
_detect_constructor_requirements
Detect if constructor (new method) needs specific parameters.
Analyzes the new method to determine required parameters.
_detect_external_object_dependency
Detect if method depends on objects from other classes.
Patterns: - Creates objects of other classes - Calls methods on objects from other classes - Receives objects as parameters
_extract_default_value
Extract default values from common Perl patterns:
Patterns: - $param = $param || 'default_value' - $param //= 'default_value' - $param = defined $param ? $param : 'default' - $param = 'default' unless defined $param; - $param = $arg // 'default' - $param ||= 'default'
Returns the default value as a string if found, undef otherwise.
_clean_default_value
Clean and normalize extracted default values.
Handles: - Removing quotes from strings - Converting numeric strings to actual numbers - Handling boolean values - Removing parentheses
_log
Log a message if verbose mode is on.
NOTES
This is pre-pre-alpha proof of concept code. Nevertheless, it is useful for creating a template which you can modify to create a working schema to pass into App::Test::Generator.
SEE ALSO
App::Test::Generator - Generate fuzz and corpus-driven test harnesses
Output from this module serves as input to that module. So with well-documented code, you can automatically create your tests.
App::Test::Generator::Template - Template of the file of tests created by
App::Test::Generator
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
Portions of this module's initial design and documentation were created with the assistance of AI.