Extensive POE Testing PT. 4 - Testing, Event Count

xsawyerx on 2009-10-18T11:43:02

update: fixed a few errors

So it took some time, but here's the next article/post on POE testing.

The last one discussed Sequence Ordered tests, which is the way I call the type of tests that do not rely on whether the event ran at the specified order by number, but by previously running events. However, all the previous posts still ignored a serious need that we have for event testing, which is how many times did each event really run?

If you use ordered tests, you cannot have the same event running more than once without some logic to test the specific iteration of the event. sequence ordered tests help reduce that but they also reduce the count.

Let us take a look at code which runs the same event more than once:

package Session;
use MooseX::POE;

my $count  = 0;

sub START           { $_[KERNEL]->yield('next')  }
event 'next' => sub { $_[KERNEL]->yield('more')  };

event 'more' => sub {
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub { print "last!\n"; };

Now let's add tests:

package Session;
use MooseX::POE;
use Test::More tests => 4;

my %events = ();
my $count  = 0;

sub START {
    $events{'START'}++;
    $_[KERNEL]->yield('next');
}

event 'next' => sub {
    $events{'next'}++;
    $_[KERNEL]->yield('more');
};

event 'more' => sub {
    $events{'more'}++;
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub {
    $events{'last'}++;
    print "last!\n";
};

event 'STOP' => sub {
    cmp_ok( $events{'START'}, '==', 1, 'START ran once'   );
    cmp_ok( $events{'next'},  '==', 4, 'next ran 4 times' );
    cmp_ok( $events{'more'},  '==', 4, 'last ran 4 times' );
    cmp_ok( $events{'last'},  '==', 1, 'last ran once'    );
};

This is how we could accomplish it. Here is how it's done with the current iteration of my (still yet unpublished) testing framework:

package Session;
use MooseX::POE;
use Test::More tests => 4;
with 'POE::Test::Simple'; # running title

has '+seq_ordering' => ( default => sub { {
    START => 1,
    next  => 4,
    more  => 4,
    last  => 1,
} } );

my $count = 0;

sub START {
    $_[OBJECT]->seq_order('START');
    $_[KERNEL]->yield('next');
}

event 'next' => sub {
    $_[OBJECT]->seq_order('next');
    $_[KERNEL]->yield('more');
};

event 'more' => sub {
    $_[OBJECT]->seq_order('more');
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub {
    $_[OBJECT]->seq_order('last');
    print "last!\n";
};

event 'STOP' => sub {
    $_[OBJECT]->seq_end();
};

And this is how it would look in the (hopefully) upcoming version:

package Session;
use MooseX::POE;
use Test::More tests => 4;
with 'POE::Test::Simple'; # running title

has '+seq_ordering' => ( default => sub { {
    START => 1,
    next  => 4,
    more  => 4,
    last  => 1,
} } );

my $count = 0;

sub START           { $_[KERNEL]->yield('next') }
event 'next' => sub { $_[KERNEL]->yield('more') };

event 'more' => sub {
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub { print "last!\n" };

Next post is a short one in which I'll show samples of using both event counting and sequence order (event dependencies).