use strict;
use warnings;
use Test::Fatal;
use Test::More 0.96;
use Eval::Closure qw( eval_closure );
use Specio::Declare;
use Specio::Library::Builtins;
{
my $str = t('Str');
my $int = t('Int');
my ( $str_source, $str_env ) = $str->inline_coercion_and_check('$value1');
my ( $int_source, $int_env ) = $int->inline_coercion_and_check('$value2');
my $sub
= 'sub { '
. 'my $value1 = shift;'
. 'my $value2 = shift;'
. 'my $str_val = '
. $str_source . ';'
. 'my $int_val = '
. $int_source . ';'
. 'return ($str_val, $int_val)' . ' }';
my $coerce_and_check;
is(
exception {
$coerce_and_check = eval_closure(
source => $sub,
environment => {
%{$str_env},
%{$int_env},
},
description => 'inlined coerce and check sub for str and int',
);
},
undef,
'no exception evaling a closure for str and int inlining in one sub',
);
is_deeply(
[ $coerce_and_check->( 'string', 42 ) ],
[ 'string', 42 ],
'both types pass check and are returned'
);
like(
exception { $coerce_and_check->( [], 42 ) },
qr/Validation failed for type named Str/,
'got exception passing arrayref for Str value'
);
like(
exception { $coerce_and_check->( 'string', [] ) },
qr/Validation failed for type named Int/,
'got exception passing arrayref for Int value'
);
}
{
my $enum1 = enum( Enum1 => values => [qw( foo bar baz )] );
my $enum2 = enum( Enum2 => values => [qw( a b c )] );
my ( $enum1_source, $enum1_env )
= $enum1->inline_coercion_and_check('$value1');
my ( $enum2_source, $enum2_env )
= $enum2->inline_coercion_and_check('$value2');
my $sub
= 'sub { '
. 'my $value1 = shift;'
. 'my $value2 = shift;'
. 'my $enum1_val = '
. $enum1_source . ';'
. 'my $enum2_val = '
. $enum2_source . ';'
. 'return ($enum1_val, $enum2_val)' . ' }';
my $coerce_and_check;
is(
exception {
$coerce_and_check = eval_closure(
source => $sub,
environment => {
%{$enum1_env},
%{$enum2_env},
},
description => 'inlined coerce and check sub for two enums',
);
},
undef,
'no exception evaling a closure for inlining two enums in one sub',
);
is_deeply(
[ $coerce_and_check->( 'foo', 'a' ) ],
[ 'foo', 'a' ],
'both types pass check and are returned'
);
like(
exception { $coerce_and_check->( [], 'c' ) },
qr/Validation failed for type named Enum1/,
'got exception passing arrayref for Enum1 value'
);
like(
exception { $coerce_and_check->( 'bar', [] ) },
qr/Validation failed for type named Enum2/,
'got exception passing arrayref for Enum2 value'
);
}
done_testing();