use strict;
use warnings;
use Test::More;
use Test::Fatal;
use Class::MOP;
my $instance;
{
package Foo;
sub new {
my $class = shift;
$instance = bless {@_}, $class;
return $instance;
}
sub foo { shift->{foo} }
}
{
package Foo::Sub;
use parent -norequire => 'Foo';
use metaclass;
sub new {
my $class = shift;
$class->meta->new_object(
__INSTANCE__ => $class->SUPER::new(@_),
@_,
);
}
__PACKAGE__->meta->add_attribute(
bar => (
reader => 'bar',
initializer => sub {
my $self = shift;
my ($value, $writer, $attr) = @_;
$writer->(uc $value);
},
),
);
}
undef $instance;
is( exception {
my $foo = Foo::Sub->new;
isa_ok($foo, 'Foo');
isa_ok($foo, 'Foo::Sub');
is($foo, $instance, "used the passed-in instance");
}, undef );
undef $instance;
is( exception {
my $foo = Foo::Sub->new(foo => 'FOO');
isa_ok($foo, 'Foo');
isa_ok($foo, 'Foo::Sub');
is($foo, $instance, "used the passed-in instance");
is($foo->foo, 'FOO', "set non-CMOP constructor args");
}, undef );
undef $instance;
is( exception {
my $foo = Foo::Sub->new(bar => 'bar');
isa_ok($foo, 'Foo');
isa_ok($foo, 'Foo::Sub');
is($foo, $instance, "used the passed-in instance");
is($foo->bar, 'BAR', "set CMOP attributes");
}, undef );
undef $instance;
is( exception {
my $foo = Foo::Sub->new(foo => 'FOO', bar => 'bar');
isa_ok($foo, 'Foo');
isa_ok($foo, 'Foo::Sub');
is($foo, $instance, "used the passed-in instance");
is($foo->foo, 'FOO', "set non-CMOP constructor arg");
is($foo->bar, 'BAR', "set correct CMOP attribute");
}, undef );
{
package BadFoo;
sub new {
my $class = shift;
$instance = bless {@_};
return $instance;
}
sub foo { shift->{foo} }
}
{
package BadFoo::Sub;
use parent -norequire => 'BadFoo';
use metaclass;
sub new {
my $class = shift;
$class->meta->new_object(
__INSTANCE__ => $class->SUPER::new(@_),
@_,
);
}
__PACKAGE__->meta->add_attribute(
bar => (
reader => 'bar',
initializer => sub {
my $self = shift;
my ($value, $writer, $attr) = @_;
$writer->(uc $value);
},
),
);
}
like( exception { BadFoo::Sub->new }, qr/BadFoo=HASH.*is not a BadFoo::Sub/, "error with incorrect constructors" );
{
my $meta = Class::MOP::Class->create('Really::Bad::Foo');
like( exception {
$meta->new_object(__INSTANCE__ => (bless {}, 'Some::Other::Class'))
}, qr/Some::Other::Class=HASH.*is not a Really::Bad::Foo/, "error with completely invalid class" );
}
{
my $meta = Class::MOP::Class->create('Really::Bad::Foo::2');
for my $invalid ('foo', 1, 0, '') {
like( exception {
$meta->new_object(__INSTANCE__ => $invalid)
}, qr/The __INSTANCE__ parameter must be a blessed reference, not $invalid/, "error with unblessed thing" );
}
}
done_testing;