use
lib
qw( ./lib ./t/lib ../inc ./inc )
;
{
my
$x
;
sub
FooBarOrDoesQuux () {
$x
||= union(
FooBarOrDoesQuux
=> [FooBar, DoesQuux]) } }
isa_ok(
FooBarOrDoesQuux,
'Type::Tiny::Union'
,
'FooBarOrDoesQuux'
,
);
isa_ok(
FooBarOrDoesQuux->[0],
'Type::Tiny::Class'
,
'FooBarOrDoesQuux->[0]'
,
);
isa_ok(
FooBarOrDoesQuux->[1],
'Type::Tiny::Role'
,
'FooBarOrDoesQuux->[1]'
,
);
is(
FooBarOrDoesQuux.
""
,
'FooBar|DoesQuux'
,
'stringification good'
,
);
my
$something
=
bless
[] =>
do
{
sub
DOES {
return
1
if
$_
[1] eq
'Quux'
;
$_
[0]->isa(
$_
[0]);
}
__PACKAGE__;
};
should_pass(
"Foo::Bar"
->new, FooBarOrDoesQuux);
should_pass(
"Foo::Baz"
->new, FooBarOrDoesQuux);
should_pass(
$something
, FooBarOrDoesQuux);
my
$something_else
=
bless
[] =>
do
{
sub
DOES {
return
1
if
$_
[1] eq
'Else'
;
$_
[0]->isa(
$_
[0]);
}
__PACKAGE__;
};
should_fail(
$something_else
, FooBarOrDoesQuux);
should_fail(
"Foo::Bar"
, FooBarOrDoesQuux);
should_fail(
"Foo::Baz"
, FooBarOrDoesQuux);
{
my
$x
;
sub
NotherUnion () {
$x
||= union(
NotherUnion
=> [BigInteger, FooBarOrDoesQuux, SmallInteger]) } }
is(
scalar
@{+NotherUnion},
4,
"unions don't get unnecessarily deep"
,
);
{
package
Local::A::AB;
our
@ISA
=
qw(Local::A::A Local::A::B)
}
my
$c1
= union [
class_type({
class
=>
"Local::A::AB"
}),
class_type({
class
=>
"Local::A::X"
}),
];
ok(
$c1
->parent == class_type({
class
=>
"Local::A"
}),
"can climb up parents of union type constraints to find best common ancestor"
,
);
my
$c2
= union [
class_type({
class
=>
"Local::A"
}),
class_type({
class
=>
"Local::B"
}),
class_type({
class
=>
"Local::C"
}),
];
isnt(
exception {
push
@{
$c2
},
'quux'
},
undef
,
'cannot push to overloaded arrayref'
);
ok(
$c2
->parent == Types::Standard::Object(),
"can climb up parents of union type constraints to find best common ancestor (again)"
,
);
is(
$c2
->find_type_for(
bless
({},
'Local::B'
) )->class,
'Local::B'
,
'Union find_type_for'
,
);
is(
$c2
->find_type_for(
bless
({},
'Local::A::A'
) )->class,
'Local::A'
,
'Union find_type_for (less obvious)'
,
);
is(
$c2
->find_type_for(
bless
({},
'Local::A::AB'
) )->class,
'Local::A'
,
'Union find_type_for (ambiguous)'
,
);
is(
$c2
->find_type_for(
bless
({},
'Local::D'
) ),
undef
,
'Union find_type_for (none)'
,
);
ok(
(FooBar|DoesQuux)==(DoesQuux|FooBar),
'Union equals'
,
);
ok(
(FooBar|DoesQuux)!=(DoesQuux|SmallInteger),
'Union not equals'
,
);
done_testing;