Skip to content

Commit

Permalink
Implement Plack::Test OO interface re #180
Browse files Browse the repository at this point in the history
  • Loading branch information
miyagawa committed Jul 12, 2013
1 parent 12acb3f commit 1985ac4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 44 deletions.
22 changes: 18 additions & 4 deletions lib/Plack/Test.pm
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
package Plack::Test;
use strict;
use warnings;
use Carp;
use parent qw(Exporter);
our @EXPORT = qw(test_psgi);

our $Impl;
$Impl ||= $ENV{PLACK_TEST_IMPL} || "MockHTTP";

sub test_psgi {
eval "require Plack::Test::$Impl;";
sub create {
my($class, $app, @args) = @_;

my $subclass = "Plack::Test::$Impl";
eval "require $subclass";
die $@ if $@;
no strict 'refs';

$subclass->new($app, @args);
}

sub test_psgi {
if (ref $_[0] && @_ == 2) {
@_ = (app => $_[0], client => $_[1]);
}
&{"Plack::Test::$Impl\::test_psgi"}(@_);
my %args = @_;

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

my $tester = Plack::Test->create($app, %args);
$client->(sub { $tester->request(@_) });
}

1;
Expand Down
39 changes: 18 additions & 21 deletions lib/Plack/Test/MockHTTP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,26 @@ use HTTP::Response;
use HTTP::Message::PSGI;
use Try::Tiny;

sub test_psgi {
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 = shift;
$req->uri->scheme('http') unless defined $req->uri->scheme;
$req->uri->host('localhost') unless defined $req->uri->host;
my $env = $req->to_psgi;

my $res = try {
HTTP::Response->from_psgi($app->($env));
} catch {
HTTP::Response->from_psgi([ 500, [ 'Content-Type' => 'text/plain' ], [ $_ ] ]);
};

$res->request($req);
return $res;
sub new {
my($class, $app) = @_;
bless { app => $app }, $class;
}

sub request {
my($self, $req) = @_;

$req->uri->scheme('http') unless defined $req->uri->scheme;
$req->uri->host('localhost') unless defined $req->uri->host;
my $env = $req->to_psgi;

my $res = try {
HTTP::Response->from_psgi($self->{app}->($env));
} catch {
HTTP::Response->from_psgi([ 500, [ 'Content-Type' => 'text/plain' ], [ $_ ] ]);
};

$client->($cb);
$res->request($req);
return $res;
}

1;
Expand Down
42 changes: 23 additions & 19 deletions lib/Plack/Test/Server.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,36 @@ use Test::TCP;
use Plack::Loader;
use Plack::LWPish;

sub test_psgi {
my %args = @_;
sub new {
my($class, $app, %args) = @_;

my $client = delete $args{client} or croak "client test code needed";
my $app = delete $args{app} or croak "app needed";
my $ua = delete $args{ua} || Plack::LWPish->new;

test_tcp(
client => sub {
my $port = shift;
my $cb = sub {
my $req = shift;
$req->uri->scheme('http');
$req->uri->host($args{host} || '127.0.0.1');
$req->uri->port($port);
return $ua->request($req);
};
$client->($cb);
},
server => $args{server} || sub {
my $server = Test::TCP->new(
code => sub {
my $port = shift;
my $server = Plack::Loader->auto(port => $port, host => ($args{host} || '127.0.0.1'));
$server->run($app);
exit;
},
);

bless { server => $server, %args }, $class;
}

sub port {
my $self = shift;
$self->{server}->port;
}

sub request {
my($self, $req) = @_;

my $ua = $self->{ua} || Plack::LWPish->new;

$req->uri->scheme('http');
$req->uri->host($self->{host} || '127.0.0.1');
$req->uri->port($self->port);

return $ua->request($req);
}

1;
Expand Down

0 comments on commit 1985ac4

Please sign in to comment.