1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Test::Fatal;
use Test::Metrics::Any;
use Test::Refcount;
use IO::Async::Notifier;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
is_refcount( $loop, 2, '$loop has refcount 2 initially' );
{
package TestNotifier;
use base qw( IO::Async::Notifier );
sub new
{
my $self = shift->SUPER::new;
( $self->{varref} ) = @_;
return $self;
}
sub _add_to_loop
{
my $self = shift;
${ $self->{varref} } = 1;
}
sub _remove_from_loop
{
my $self = shift;
${ $self->{varref} } = 0;
}
}
# $loop->add
{
my $notifier = TestNotifier->new( \my $in_loop );
is_deeply( [ $loop->notifiers ],
[],
'$loop->notifiers empty' );
is( $notifier->loop, undef, 'loop undef' );
$loop->add( $notifier );
is_refcount( $loop, 2, '$loop has refcount 2 adding Notifier' );
is_refcount( $notifier, 2, '$notifier has refcount 2 after adding to Loop' );
is( $notifier->loop, $loop, 'loop $loop' );
is_deeply( [ $loop->notifiers ],
[ $notifier ],
'$loop->notifiers contains new Notifier' );
ok( $in_loop, '_add_to_loop called' );
ok( exception { $loop->add( $notifier ) }, 'adding again produces error' );
$loop->remove( $notifier );
is( $notifier->loop, undef, '$notifier->loop is undef' );
is_deeply( [ $loop->notifiers ],
[],
'$loop->notifiers empty once more' );
ok( !$in_loop, '_remove_from_loop called' );
is_oneref( $notifier, '$notifier has refcount 1 finally' );
}
# parent/child in Loop
{
my $parent = TestNotifier->new( \my $parent_in_loop );
my $child = TestNotifier->new( \my $child_in_loop );
$loop->add( $parent );
$parent->add_child( $child );
is_refcount( $child, 3, '$child has refcount 3 after add_child within loop' );
is( $parent->loop, $loop, '$parent->loop is $loop' );
is( $child->loop, $loop, '$child->loop is $loop' );
ok( $parent_in_loop, '$parent now in loop' );
ok( $child_in_loop, '$child now in loop' );
ok( exception { $loop->remove( $child ) }, 'Directly removing a child from the loop fails' );
$loop->remove( $parent );
is_deeply( [ $parent->children ], [ $child ], '$parent->children after $loop->remove' );
is_oneref( $parent, '$parent has refcount 1 after removal from loop' );
is_refcount( $child, 2, '$child has refcount 2 after removal of parent from loop' );
is( $parent->loop, undef, '$parent->loop is undef' );
is( $child->loop, undef, '$child->loop is undef' );
ok( !$parent_in_loop, '$parent no longer in loop' );
ok( !$child_in_loop, '$child no longer in loop' );
ok( exception { $loop->add( $child ) }, 'Directly adding a child to the loop fails' );
$loop->add( $parent );
is( $child->loop, $loop, '$child->loop is $loop after remove/add parent' );
ok( $parent_in_loop, '$parent now in loop' );
ok( $child_in_loop, '$child now in loop' );
$loop->remove( $parent );
$parent->remove_child( $child );
is_oneref( $parent, '$parent has refcount 1 finally' );
is_oneref( $child, '$child has refcount 1 finally' );
}
# Metrics
SKIP: {
skip "Metrics are unavailable" unless $IO::Async::Metrics::METRICS;
my $notifier = TestNotifier->new( \my $tmp );
$loop->add( $notifier );
is_metrics( { io_async_notifiers => 1 },
'$loop->add increments notifiers count' );
$loop->remove( $notifier );
is_metrics( { io_async_notifiers => 0 },
'$loop->remove decrements notifiers count' );
}
is_refcount( $loop, 2, '$loop has refcount 2 finally' );
done_testing;
|