use strict;
use warnings;
use Test::More;
use Test::Fatal;
{
use Moose::Util::TypeConstraints;
use Carp 'confess';
subtype 'Death', as 'Int', where { $_ == 1 };
coerce 'Death', from 'Any', via { confess };
}
{
my ($attr_foo_line, $attr_bar_line, $ctor_line);
{
package Foo;
use Moose;
has foo => (
is => 'rw',
isa => 'Death',
coerce => 1,
);
$attr_foo_line = __LINE__ - 5;
has bar => (
accessor => 'baz',
isa => 'Death',
coerce => 1,
);
$attr_bar_line = __LINE__ - 5;
__PACKAGE__->meta->make_immutable;
$ctor_line = __LINE__ - 1;
}
like(
exception { Foo->new(foo => 2) },
qr/\Qcalled at constructor Foo::new (defined at $0 line $ctor_line)\E/,
"got definition context for the constructor"
);
like(
exception { my $f = Foo->new(foo => 1); $f->foo(2) },
qr/\Qcalled at accessor Foo::foo (defined at $0 line $attr_foo_line)\E/,
"got definition context for the accessor"
);
like(
exception { my $f = Foo->new(foo => 1); $f->baz(2) },
qr/\Qcalled at accessor Foo::baz of attribute bar (defined at $0 line $attr_bar_line)\E/,
"got definition context for the accessor"
);
}
{
my ($dtor_line);
{
package Bar;
use Moose;
# just dying here won't work, because perl's exception handling is
# terrible
sub DEMOLISH { try { confess } catch { warn $_ } }
__PACKAGE__->meta->make_immutable;
$dtor_line = __LINE__ - 1;
}
{
my $warning = '';
local $SIG{__WARN__} = sub { $warning .= $_[0] };
{ Bar->new }
like(
$warning,
qr/\Qcalled at destructor Bar::DESTROY (defined at $0 line $dtor_line)\E/,
"got definition context for the destructor"
);
}
}
done_testing;