X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=t%2F020_attributes%2F036_clone_weak.t;fp=t%2F020_attributes%2F036_clone_weak.t;h=db42d7eebe99cdf5ecc68b2c2efb917a8556f1e4;hp=0000000000000000000000000000000000000000;hb=f1575d9f6d73252e751770a6c7ac717237059f29;hpb=7f627364a9120ef321d5903f33fb2522657817eb diff --git a/t/020_attributes/036_clone_weak.t b/t/020_attributes/036_clone_weak.t new file mode 100644 index 0000000..db42d7e --- /dev/null +++ b/t/020_attributes/036_clone_weak.t @@ -0,0 +1,181 @@ +use strict; +use warnings; +use Test::More; + +{ + package Foo; + use Mouse; + + has bar => ( + is => 'ro', + weak_ref => 1, + ); +} + +{ + package MyScopeGuard; + + sub new { + my ($class, $cb) = @_; + bless { cb => $cb }, $class; + } + + sub DESTROY { shift->{cb}->() } +} + +{ + my $destroyed = 0; + + my $foo = do { + my $bar = MyScopeGuard->new(sub { $destroyed++ }); + my $foo = Foo->new({ bar => $bar }); + my $clone = $foo->meta->clone_object($foo); + + is $destroyed, 0; + + $clone; + }; + + isa_ok($foo, 'Foo'); + is $foo->bar, undef; + is $destroyed, 1; +} + +{ + my $clone; + { + my $anon = Mouse::Meta::Class->create_anon_class; + + my $foo = $anon->new_object; + isa_ok($foo, $anon->name); + ok(Mouse::Util::class_of($foo), "has a metaclass"); + + $clone = $anon->clone_object($foo); + isa_ok($clone, $anon->name); + ok(Mouse::Util::class_of($clone), "has a metaclass"); + } + + ok(Mouse::Util::class_of($clone), "still has a metaclass"); +} + +=pod + +{ + package Foo::Meta::Attr::Trait; + use Mouse::Role; + + has value_slot => ( + is => 'ro', + isa => 'Str', + lazy => 1, + default => sub { shift->name }, + ); + + has count_slot => ( + is => 'ro', + isa => 'Str', + lazy => 1, + default => sub { '<>' . shift->name }, + ); + + sub slots { + my $self = shift; + return ($self->value_slot, $self->count_slot); + } + + sub _set_count { + my $self = shift; + my ($instance) = @_; + my $mi = $self->associated_class->get_meta_instance; + $mi->set_slot_value( + $instance, + $self->count_slot, + ($mi->get_slot_value($instance, $self->count_slot) || 0) + 1, + ); + } + + sub _clear_count { + my $self = shift; + my ($instance) = @_; + $self->associated_class->get_meta_instance->deinitialize_slot( + $instance, $self->count_slot + ); + } + + sub has_count { + my $self = shift; + my ($instance) = @_; + $self->associated_class->get_meta_instance->has_slot_value( + $instance, $self->count_slot + ); + } + + sub count { + my $self = shift; + my ($instance) = @_; + $self->associated_class->get_meta_instance->get_slot_value( + $instance, $self->count_slot + ); + } + + after set_initial_value => sub { + shift->_set_count(@_); + }; + + after set_value => sub { + shift->_set_count(@_); + }; + + around _inline_instance_set => sub { + my $orig = shift; + my $self = shift; + my ($instance) = @_; + + my $mi = $self->associated_class->get_meta_instance; + + return 'do { ' + . $mi->inline_set_slot_value( + $instance, + $self->count_slot, + $mi->inline_get_slot_value( + $instance, $self->count_slot + ) . ' + 1' + ) . ';' + . $self->$orig(@_) + . '}'; + }; + + after clear_value => sub { + shift->_clear_count(@_); + }; +} + +{ + package Bar; + use Mouse; + Mouse::Util::MetaRole::apply_metaroles( + for => __PACKAGE__, + class_metaroles => { + attribute => ['Foo::Meta::Attr::Trait'], + }, + ); + + has baz => ( is => 'rw' ); +} + +{ + my $attr = Bar->meta->find_attribute_by_name('baz'); + + my $bar = Bar->new(baz => 1); + is($attr->count($bar), 1, "right count"); + + $bar->baz(2); + is($attr->count($bar), 2, "right count"); + + my $clone = $bar->meta->clone_object($bar); + is($attr->count($clone), $attr->count($bar), "right count"); +} + +=cut + +done_testing;