use strict;
use warnings;
use IO::Async::PSGI;
use IO::Async::Loop;
use IO::Async::Test;
use HTTP::Request;
use HTTP::Message::PSGI;
use Plack::Util;
use Plack::Builder;
use HTTP::Exception;
use Test2::Bundle::Extended;
use Data::Printer;
my $loop = IO::Async::Loop->new;
testing_loop $loop;
my $app_f = sub {
my $f = $_[0]->{'io.async.loop'}
->delay_future(after=>0.2);
if ($_[0]->{PATH_INFO} =~ /fail/) {
return $f->then_fail("Expected failure\n");
}
if ($_[0]->{PATH_INFO} =~ /exc/) {
return $f->then_fail(
HTTP::Exception::401->throw(
status_message => 'Expected failure',
),
);
}
return $f->then_done([200,[],['coderef']]);
};
my $psgi = IO::Async::PSGI->new({
app => $app_f,
});
my $app = $psgi->psgi_app;
my $success = [200,[],['coderef']];
my $fail_500 = [ 500, array { etc; }, [ "Expected failure\n" ] ];
my $fail_401 = [ 401, array { etc; }, [ 'Expected failure' ] ];
my %cases = (
success => $success,
'/success' => $success,
fail => $fail_500,
'/fail' => $fail_500,
exception => $fail_401,
'/exception' => $fail_401,
);
sub run_test {
my ($use_loop) = @_;
for my $c (sort keys %cases) {
subtest $c => sub {
my $req = HTTP::Request->new(
GET => "http://localhost/$c",
)->to_psgi;
$req->{'io.async.loop'}=$loop
if $use_loop;
my $raw_res = $app->($req);
my $res;
ref_ok(
$raw_res,
'CODE',
'got a delayed response',
);
$raw_res->(sub{$res=shift});
wait_for { $res } if $use_loop;
Plack::Util::header_remove($res->[1],'X-Request-Id');
is(
$res,
$cases{$c},
'correct response',
np $res,
);
}
}
}
subtest 'with loop' => sub { run_test(1) };
subtest 'without loop' => sub { run_test(0) };
done_testing;