NAME
    POE::Test::Helpers - Testing framework for POE

VERSION
    version 1.11

SYNOPSIS
    This module provides you with a framework to easily write tests for your
    POE code.

    The main purpose of this module is to be non-instrusive (nor abstrusive)
    and allow you to write your code without getting in your way.

        use Test::More tests => 1;
        use POE;
        use POE::Test::Helpers;

        # defining a callback to create a session
        my $run = sub {
            return POE::Session->create(
                inline_states => {
                    '_start' => sub {
                        print "Start says hi!\n";
                        $_[KERNEL]->yield('next');
                    },
                    'next' => sub { print "Next says hi!\n" },
                }
            );
        };

        # here we define the tests
        # and tell POE::Test::Helpers to run your session
        POE::Test::Helpers->spawn(
            run   => $run,
            tests => {
                # _start is actually 0
                # next will run right after _start
                next => { order => 1 },
            },
        );

        POE::Kernel->run;

    Testing event-based programs is not trivial at all. There's a lot of
    hidden race conditions and unknown behavior afoot. Usually we separate
    the testing to components, subroutines and events. However, as good as
    it is (and it's good!), it doesn't give us the exact behavior we'll get
    from the application once running.

    There are also a lot of types of tests that we would want to run, such
    as:

    *   Ordered Events:

        Did every event run in the specific order I wanted it to?

        *(maybe some event was called first instead of third...)*

    *   Sequence Ordered Events:

        Did every event run only after other events?

        Imagine you want to check whether "run_updates" ran, but you know it
        can should only run after "get_main_status" ran. In event-based
        programming, you would give up the idea of testing this possible
        race condition, but with Test::POE::Helpers you can test it.

        *"run_updates" can only run after "get_main_status"*

    *   Event Counting:

        How many times can each event run?

        *(this event can be run only 4 times, no more, no less)*

    *   Ordered Event Parameters:

        Checking specific parameters an event received, supporting multiple
        options.

        *(did this event get the right parameters for each call?)*

    *   Unordered Event Parameters:

        Same thing, just without having a specific order of sets of events.

    This module allows to do all those things using a simple API.

METHODS
  spawn
    Creates a new POE::Session that manages in the background the tests. If
    you wish not to create a session, but manage things yourself, check
    "new" below and the additionally available methods.

    Accepts the following options:

   run
    A callback to create your session. This is required so
    POE::Test::Helpers could hook up to your code internally without you
    having to set up hooks for it.

    The callback is expected to return the session object. This means that
    you can either provide a code reference to your "POE::Session->create()"
    call or you could set up an arbitrary code reference that just returns a
    session object you want to monitor.

        use POE::Test::Helpers;

        # we want to test Our::Module
        POE::Test::Helpers->spawn(
            run => sub { Our::Module->spawn( ... ) },
            ...
        );

        # or, if we want to set up the session ourselves in more intricate ways
        my $object = Our::Module->new( ... );
        my $code   = sub { $object->create_session };

        POE::Test::Helpers->spawn(
            run => $code,
            ...
        );

        POE::Kernel->run;

    In case you want to simply run a test in an asynchronous way (and that
    is why you're using POE), you could do it this way:

        use POE::Test::Helpers;

        sub start {
            # POE code
            $_[KERNEL]->yield('next');
        }

        sub next {
            # POE code
        }

        # now provide POE::Test::Helpers with a coderef that creates a POE::Session
        POE::Test::Helpers->spawn(
            run => sub {
                POE::Session->create(
                    inline_states => [ qw/ _start next / ],
                );
            },
        );

        POE::Kernel->run;

   tests
    Describes what tests should be done. You need to provide each event that
    will be tested and what is tested with it and how. There are a lot of
    different tests that are available for you.

    You can provide multiple tests per event, as much as you want.

        POE::Test::Helpers->spawn(
            run   => $run_method,
            tests => {
                # testing that "next" was run once
                next => { count => 1 },

                # testing that "more" wasn't run at all
                more => { count => 0 },

                # testing that "again" was run 3 times
                # and that "next" was run beforehand
                again => {
                    count => 3,
                    deps  => ['next'],
                },

                # testing that "last" was run 4th
                # and what were the subroutine parameters each time
                last => {
                    order  => 3, # 0 is first, 1 is second...
                    params => [ [ 'first', 'params' ], ['second'] ],
                },
            },
        );

        POE::Kernel->run;

   params_type
    Ordinarily, the params are checked in an *ordered* fashion. This means
    that it checks the first ones against the first arrayref, the second one
    against the second and so on.

    However, sometimes you just want to provide a few sets of *possible*
    parameters which means it *might* be one of these, but not necessarily
    in this order.

    This helps in case of race conditions when you don't know what comes
    first and frankly don't even care.

    You can change this simply by setting this attribute to "unordered".

        use POE::Test::Helpers;

        POE::Test::Helpers->spawn(
            run          => $run_method,
            event_params => 'unordered',
            tests        => {
                checks => {
                    # either called with "now" or "then" parameters
                    # doesn't matter the order
                    params => [ ['now'], ['then'] ],
                },
            },
        );

        POE::Kernel->run;

  new
    Creates the underlying object. Please review POE::Test::Helpers::API for
    this.

  reached_event
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

  check_deps
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

  check_order
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

  check_params
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

  check_all_counts
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

  check_count
    Underlying object method. Please review POE::Test::Helpers::API for
    this.

AUTHOR
    Sawyer X, "<xsawyerx at cpan.org>"

BUGS
    Please use the Github Issues tracker.

SUPPORT
    You can find documentation for this module with the perldoc command.

        perldoc POE::Test::Helpers

    You can also look for information at:

    *   RT: CPAN's request tracker

        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=POE-Test-Helpers>

    *   AnnoCPAN: Annotated CPAN documentation

        <http://annocpan.org/dist/POE-Test-Helpers>

    *   CPAN Ratings

        <http://cpanratings.perl.org/d/POE-Test-Helpers>

    *   Search CPAN

        <http://search.cpan.org/dist/POE-Test-Helpers/>

ACKNOWLEDGEMENTS
    I owe a lot of thanks to the following people:

    *   Chris (perigrin) Prather

        Thanks for all the comments and ideas. Thanks for MooseX::POE!

    *   Rocco (dngor) Caputo

        Thanks for the input and ideas. Thanks for POE!

    *   #moose and #poe

        Really great people and constantly helping me with stuff, including
        one of the core principles in this module.

AUTHOR
      Sawyer X <xsawyerx@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2010 by Sawyer X.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

