App-Test-Generator
view release on metacpan or search on metacpan
t/SchemaExtractor.t view on Meta::CPAN
ok(exists $fields->{port}, 'field with default detected');
is($fields->{port}{_default}, 3306, 'default value extracted');
ok($fields->{port}{optional}, 'field with default is optional');
# Field with :isa type constraint -- type set to object
$fields = $fn->("field \$logger :param :isa(Log::Any);\n");
ok(exists $fields->{logger}, 'field with isa detected');
is($fields->{logger}{isa}, 'Log::Any', 'isa type extracted');
is($fields->{logger}{type}, 'object', 'type set to object for isa');
done_testing();
};
# ==================================================================
# _parse_signature_parameter
# --------------------------------------------------
# Tests for the individual signature parameter parser
# ==================================================================
subtest '_parse_signature_parameter' => sub {
my $e = _extractor();
my $fn = sub { $e->_parse_signature_parameter(@_) };
# Plain scalar parameter at position 0
my $info = $fn->('$name', 0);
is($info->{name}, 'name', 'plain param name extracted');
is($info->{position}, 0, 'position set correctly');
is($info->{optional}, 0, 'plain param is required');
# Parameter with a numeric default value makes it optional
$info = $fn->('$port = 3306', 1);
is($info->{name}, 'port', 'default param name extracted');
is($info->{optional}, 1, 'param with default is optional');
is($info->{_default}, 3306, 'default value extracted');
is($info->{position}, 1, 'position set correctly');
# Parameter with :Int type constraint maps to 'integer'
$info = $fn->('$count :Int', 0);
is($info->{name}, 'count', 'typed param name extracted');
is($info->{type}, 'integer', ':Int maps to integer type');
is($info->{optional}, 0, 'typed param without default is required');
# Parameter with :Num constraint and default
$info = $fn->('$ratio :Num = 1.0', 0);
is($info->{type}, 'number', ':Num maps to number type');
is($info->{optional}, 1, 'typed param with default is optional');
# Slurpy array parameter
$info = $fn->('@args', 2);
is($info->{name}, 'args', 'slurpy array name extracted');
is($info->{type}, 'array', 'slurpy array has array type');
ok($info->{slurpy}, 'slurpy flag set for @param');
ok($info->{optional}, 'slurpy array is optional');
# Slurpy hash parameter
$info = $fn->('%opts', 2);
is($info->{name}, 'opts', 'slurpy hash name extracted');
is($info->{type}, 'hash', 'slurpy hash has hash type');
ok($info->{slurpy}, 'slurpy flag set for %param');
# Non-matching pattern returns undef without dying
is($fn->('not_a_param', 0), undef, 'non-matching pattern returns undef');
done_testing();
};
# ==================================================================
# _infer_type_from_expression
# --------------------------------------------------
# Tests for the return expression type inferrer.
# This function checks booleans (^[01]$) BEFORE integers
# so single 0 and 1 are correctly classified as boolean.
# ==================================================================
subtest '_infer_type_from_expression' => sub {
my $e = _extractor();
my $fn = sub { $e->_infer_type_from_expression(@_) };
# Undef returns scalar as the safe default
is($fn->(undef)->{type}, 'scalar', 'undef expr returns scalar type');
# Array-like expressions
is($fn->('@array')->{type}, 'array', '@array is array');
is($fn->('qw(a b c)')->{type}, 'array', 'qw() is array');
is($fn->('\@ref')->{type}, 'arrayref', '\@ref is arrayref');
is($fn->('[1,2,3]')->{type}, 'arrayref', '[...] is arrayref');
# Hash-like expressions
is($fn->('\%hash')->{type}, 'hashref', '\%hash is hashref');
is($fn->('{}')->{type}, 'hashref', '{} is hashref');
# Numeric scalar literals
is($fn->('42')->{type}, 'integer', 'integer literal');
is($fn->('-1')->{type}, 'integer', 'negative integer');
is($fn->('3.14')->{type}, 'number', 'float literal');
# String literal
is($fn->("'hello'")->{type}, 'string', 'single-quoted string');
# Single-digit 0 and 1 are boolean -- the boolean check /^[01]$/
# appears before the integer check in the function after the bug fix
is($fn->('1')->{type}, 'boolean', '1 is boolean in expression context');
is($fn->('0')->{type}, 'boolean', '0 is boolean in expression context');
# scalar() function returns integer with min 0
my $res = $fn->('scalar(@arr)');
is($res->{type}, 'integer', 'scalar() returns integer');
is($res->{min}, 0, 'scalar() has min 0');
# Comma-separated values indicate an array
is($fn->('$a, $b')->{type}, 'array', 'comma-separated is array');
# length() returns integer with min 0
$res = $fn->('length($s)');
is($res->{type}, 'integer', 'length() returns integer');
is($res->{min}, 0, 'length() has min 0');
done_testing();
};
# ==================================================================
# _calculate_input_confidence
# --------------------------------------------------
( run in 0.529 second using v1.01-cache-2.11-cpan-9581c071862 )