use
lib
qw( ./lib ./t/lib ../inc ./inc )
;
ok(
"Type::Tiny"
->can(
'new'
),
'Type::Tiny can works for valid methods'
);
ok(
!
"Type::Tiny"
->can(
'will_never_be_a_method'
),
'Type::Tiny can works for invalid methods'
);
my
$Any
=
"Type::Tiny"
->new(
name
=>
"Any"
);
ok(!
$Any
->is_anon,
"Any is not anon"
);
is(
$Any
->name,
"Any"
,
"Any is called Any"
);
ok(
$Any
->can_be_inlined,
'Any can be inlined'
);
should_pass(
$_
,
$Any
)
for
1, 1.2,
"Hello World"
, [], {},
undef
, \
*STDOUT
;
like(
exception {
$Any
->create_child_type(
name
=>
"1"
) },
qr{^"1" is not a valid type name}
,
"bad type constraint name"
,
);
my
$Int
=
$Any
->create_child_type(
constraint
=>
sub
{
defined
(
$_
) and !
ref
(
$_
) and
$_
=~ /^[+-]?[0-9]+$/sm },
);
ok(
$Int
->is_anon,
"\$Int is anon"
);
is(
$Int
->name,
"__ANON__"
,
"\$Int is called __ANON__"
);
ok(!
$Int
->can_be_inlined,
'$Int cannot be inlined'
);
should_pass(
$_
,
$Int
)
for
1, -1, 0, 100, 10000, 987654;
should_fail(
$_
,
$Int
)
for
1.2,
"Hello World"
, [], {},
undef
, \
*STDOUT
;
ok_subtype(
$Any
,
$Int
);
ok(
$Any
->is_supertype_of(
$Int
),
'Any is_supertype_of $Int'
);
ok(
$Int
->is_a_type_of(
$Any
),
'$Int is_a_type_of Any'
);
ok(
$Int
->is_a_type_of(
$Int
),
'$Int is_a_type_of $Int'
);
ok(!
$Int
->is_subtype_of(
$Int
),
'not $Int is_subtype_of $Int'
);
my
$Below
=
$Int
->create_child_type(
name
=>
"Below"
,
constraint_generator
=>
sub
{
my
$param
=
shift
;
return
sub
{
$_
<
$param
};
},
);
ok(
$Below
->is_parameterizable,
'Below is_parameterizable'
);
ok(!
$Below
->is_parameterized,
'not Below is_parameterized'
);
should_pass(
$_
,
$Below
)
for
1, -1, 0, 100, 10000, 987654;
should_fail(
$_
,
$Below
)
for
1.2,
"Hello World"
, [], {},
undef
, \
*STDOUT
;
my
$Below5
=
$Below
->parameterize(5);
ok(
$Below5
->is_anon,
'$Below5 is anon'
);
is(
$Below5
->display_name,
'Below[5]'
,
'... but still has a nice display name'
);
should_pass(
$_
,
$Below5
)
for
1, -1, 0;
should_fail(
$_
,
$Below5
)
for
1.2,
"Hello World"
, [], {},
undef
, \
*STDOUT
, 100, 10000, 987654;
ok_subtype(
$_
,
$Below5
)
for
$Any
,
$Int
,
$Below
;
ok(
$Below5
->is_parameterized,
'Below[5] is_parameterized'
);
ok(!
$Below
->has_parameters,
'has_parameters method works - negative'
);
ok(
$Below5
->has_parameters,
'has_parameters method works - positive'
);
is_deeply(
$Below5
->parameters, [5],
'parameters method works'
);
my
$Ref
=
"Type::Tiny"
->new(
name
=>
"Ref"
,
constraint
=>
sub
{
ref
(
$_
) },
inlined
=>
sub
{
"ref($_)"
},
);
my
$ArrayRef
=
"Type::Tiny"
->new(
name
=>
"ArrayRef"
,
parent
=>
$Ref
,
constraint
=>
sub
{
ref
(
$_
) eq
'ARRAY'
},
inlined
=>
sub
{
undef
,
"ref($_) eq 'ARRAY'"
},
);
is(
$ArrayRef
->inline_check(
'$xxx'
),
q[(((ref($xxx))) && (ref($xxx) eq 'ARRAY'))]
,
'inlining stuff can return a list'
,
);
{
my
$subtype_of_Num
= Types::Standard::Num->create_child_type;
my
$subtype_of_Int
= Types::Standard::Int->create_child_type;
ok(
$subtype_of_Int
->is_subtype_of(
$subtype_of_Num
),
'loose subtype comparison 1'
,
);
ok(
!
$subtype_of_Int
->is_strictly_subtype_of(
$subtype_of_Num
),
'strict subtype comparison 1'
,
);
ok(
$subtype_of_Num
->is_supertype_of(
$subtype_of_Int
),
'loose supertype comparison 1'
,
);
ok(
!
$subtype_of_Num
->is_strictly_supertype_of(
$subtype_of_Int
),
'strict supertype comparison 1'
,
);
ok(
Types::Standard::Int->is_subtype_of( Types::Standard::Num ),
'loose subtype comparison 2'
,
);
ok(
Types::Standard::Int->is_strictly_subtype_of( Types::Standard::Num ),
'strict subtype comparison 2'
,
);
ok(
Types::Standard::Num->is_supertype_of( Types::Standard::Int ),
'loose supertype comparison 2'
,
);
ok(
Types::Standard::Num->is_strictly_supertype_of( Types::Standard::Int ),
'strict supertype comparison 2'
,
);
}
my
$t1
= Types::Standard::Int;
my
$t2
=
$t1
->create_child_type(
name
=>
'T2'
);
my
$t3
=
$t2
->create_child_type(
name
=>
'T3'
);
my
$t4
=
$t3
->create_child_type(
name
=>
'T4'
);
my
$t5
=
$t4
->create_child_type(
name
=>
'T5'
);
my
$t6
=
$t5
->create_child_type(
name
=>
'T6'
);
my
$found
=
$t6
->find_parent(
sub
{
$_
->has_parent and
$_
->parent->name eq
'Int'
});
is(
$found
->name,
'T2'
,
'find_parent (scalar context)'
);
my
(
$found2
,
$n2
) =
$t6
->find_parent(
sub
{
$_
->has_parent and
$_
->parent->name eq
'Int'
});
is(
$found2
->name,
'T2'
,
'find_parent (list context)'
);
is(
$n2
, 4,
'... includes a count'
);
my
(
$found3
,
$n3
) =
$t6
->find_parent(
sub
{
$_
->name eq
'Kristoff'
});
is(
$found3
,
undef
,
'find_parent (null result)'
);
is($3,
undef
,
'... includes an undef count'
);
{
my
$Any
=
"Type::Tiny"
->new(
name
=>
"Any"
);
my
$Blah
=
$Any
->create_child_type->create_child_type(
constraint
=>
sub
{
"yes"
});
my
$Bleh
=
$Blah
->create_child_type(
name
=>
"Bleh"
)->create_child_type;
is(
$Bleh
->find_constraining_type->{uniq},
$Blah
->{uniq},
'find_constraining_type'
);
}
done_testing;