Plack-Test-AnyEvent

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Plack-Test-AnyEvent

0.08 July 19 2017
     Fix GH #3 - streaming apps hang on Windows (thanks to Alexandr Ciornii for reporting, and Paul Cochrane for helping me work on Windows)

0.07 July 03 2017
     Fix some dist issues (thanks, Paul Cochrane!)

0.06 January 26 2015
     Fix an issue with PSGI conformance (thanks, Daisuke Maki!)

0.05 October 20 2013
     Allow on_content_received to work for non-streaming responses. Maki-Daisuke++

0.04 May 23 2013
     Fix broken test.

0.03 August 31 2011
     Fix to work with AnyEvent 6.

0.02 August 16 2011
     Added support for uncaught exceptions being thrown in applications.

MANIFEST  view on Meta::CPAN

lib/Plack/Test/AnyEvent.pm
lib/Plack/Test/AnyEvent/Response.pm
t/00-compile.t
t/01-ae.t
t/02-anyevent.t
t/03-cocoa.t
t/03-ev.t
t/03-event.t
t/03-glib.t
t/03-perl.t
t/04-non-streaming-response-callback.t
t/lib/Plack/Test/AnyEvent/Test.pm
xt/author/critic.t
xt/author/pod-coverage.t
xt/author/pod-syntax.t
xt/release/dist-manifest.t
xt/release/kwalitee.t
xt/release/localbrew-pristine-5.10.t
xt/release/localbrew-pristine-5.12.t
xt/release/localbrew-pristine-5.14.t
xt/release/localbrew-pristine-5.16.t

lib/Plack/Test/AnyEvent.pm  view on Meta::CPAN

    my ( %args ) = @_;

    my $client = delete $args{client} or croak "client test code needed";
    my $app    = delete $args{app}    or croak "app needed";

    my $cb     = sub {
        my ( $req ) = @_;
        $req->uri->scheme('http')    unless defined $req->uri->scheme;
        $req->uri->host('localhost') unless defined $req->uri->host;
        my $env = $req->to_psgi;
        $env->{'psgi.streaming'}   = 1;
        $env->{'psgi.nonblocking'} = 1;

        my $res = $app->($env);

        if(ref($res) eq 'CODE') {
            my ( $status, $headers, $body );
            my ( $read, $write );

            my $cond = AnyEvent->condvar;

lib/Plack/Test/AnyEvent.pm  view on Meta::CPAN

=head1 SYNOPSIS

  use HTTP::Request::Common;
  use Plack::Test;

  $Plack::Test::Impl = 'AnyEvent'; # or 'AE' for short

  test_psgi $app, sub {
    my ( $cb ) = @_;

    my $res = $cb->(GET '/streaming-response');
    is $res->header('Transfer-Encoding'), 'chunked';
    $res->on_content_received(sub {
        my ( $content ) = @_;

        # test chunk of streaming response
    });
    $res->recv;
  }

=head1 DESCRIPTION

This L<Plack::Test> implementation allows you to easily test your
L<AnyEvent>-based PSGI applications.  Normally, L<Plack::Test::MockHTTP>
or L<Plack::Test::Server> work fine for this, but this implementation comes
in handy when you'd like to test your streaming results as they come in, or
if your application uses long-polling.  For non-streaming requests, you can
use this module exactly like Plack::Test::MockHTTP; otherwise, you can set
up a content handler and call C<$res-E<gt>recv>.  The event loop will then
run until the PSGI application closes its writer handle or until your test
client calls C<send> on the response.

=head1 FUNCTIONS

=head2 test_psgi

This function behaves almost identically to L<Plack::Test/test_psgi>; the

lib/Plack/Test/AnyEvent.pm  view on Meta::CPAN

the exception is propagated by C<$res-E<gt>recv>.  Here's an example:

  my $app = sub {
    die 'thrown by $cb';

    return sub {
        my ( $respond ) = @_;

        die 'still thrown by $cb';

        if($streaming) {
            my $writer = $respond->([
                200,
                ['Content-Type' => 'text/plain'],
            ]);

            die 'still thrown by $cb';

            my $timer;
            $timer = AnyEvent->timer(
                after => 2,

lib/Plack/Test/AnyEvent.pm  view on Meta::CPAN


=item Glib

=item Perl

=back

This list isn't exclusive; ie. just because your event loop isn't on this list
doesn't mean it doesn't work.  Also, even if your event loop doesn't pass
the exception tests, the general usage of this module (testing requests,
handling streaming results and long polling) should work on any AnyEvent loop.
Just don't throw any uncaught exceptions =).

=head1 SEE ALSO

L<AnyEvent>, L<Plack>, L<Plack::Test>

=begin comment

=over

t/lib/Plack/Test/AnyEvent/Test.pm  view on Meta::CPAN

        my ( $cb ) = @_;

        my $res = $cb->(GET '/');
        is $res->code, 200;
        is $res->content_type, 'text/plain';
        is $res->content, 'OK';
    };

}

sub test_streaming_app :Test(6) {
    my $app = sub {
        my ( $env ) = @_;

        return sub {
            my ( $respond ) = @_;

            my $writer = $respond->([
                200,
                ['Content-Type' => 'text/plain'],
            ]);

t/lib/Plack/Test/AnyEvent/Test.pm  view on Meta::CPAN


    test_psgi $app, sub {
        my ( $cb ) = @_;

        my $res = $cb->(GET '/');
        is $res->code, 200;
        like $res->content, qr/All Alright/;
    };
}

sub test_bad_app_streaming :Test(2) {
    my $app = sub {
        my ( $env ) = @_;

        return sub {
            my ( $respond ) = @_;

            my $timer;
            $timer = AnyEvent->timer(
                after => 0.5,
                cb    => sub {

t/lib/Plack/Test/AnyEvent/Test.pm  view on Meta::CPAN

        is $res->code, 200;
        $res->on_content_received(sub {
            # no-op
        });
        throws_ok {
            $res->recv;
        } qr/bad apple/;
    };
}

sub test_responsible_app_streaming :Test(2) {
    my $app = sub {
        my ( $env ) = @_;

        return sub {
            my ( $respond ) = @_;

            my $timer;
            $timer = AnyEvent->timer(
                after => 0.5,
                cb    => sub {



( run in 0.288 second using v1.01-cache-2.11-cpan-4d50c553e7e )