NAME
PAGI::Test::Client - Test client for PAGI applications
SYNOPSIS
use PAGI::Test::Client;
my $client = PAGI::Test::Client->new(app => $app);
# Simple GET
my $res = $client->get('/');
is $res->status, 200;
is $res->text, 'Hello World';
# GET with query parameters
my $res = $client->get('/search', query => { q => 'perl' });
# POST with JSON body
my $res = $client->post('/api/users', json => { name => 'John' });
# POST with form data
my $res = $client->post('/login', form => { user => 'admin' });
# Custom headers
my $res = $client->get('/api', headers => { Authorization => 'Bearer xyz' });
# Session cookies persist across requests
$client->post('/login', form => { user => 'admin', pass => 'secret' });
my $res = $client->get('/dashboard'); # authenticated!
DESCRIPTION
PAGI::Test::Client allows you to test PAGI applications without starting a real server. It invokes your app directly by constructing the PAGI protocol messages ($scope, $receive, $send), making tests fast and simple.
This is inspired by Starlette's TestClient but adapted for Perl and PAGI's specific features like first-class SSE support.
CONSTRUCTOR
new
my $client = PAGI::Test::Client->new(
app => $app, # Required: PAGI app coderef
headers => { ... }, # Optional: default headers
lifespan => 1, # Optional: enable lifespan (default: 0)
);
Options
- app (required)
-
The PAGI application coderef to test.
- headers
-
Default headers to include in every request. Request-specific headers override these.
- lifespan
-
If true, the client will send lifespan.startup when started and lifespan.shutdown when stopped. Default is false (most tests don't need it).
HTTP METHODS
All HTTP methods return a PAGI::Test::Response object.
get
my $res = $client->get($path, %options);
post
my $res = $client->post($path, %options);
put
my $res = $client->put($path, %options);
patch
my $res = $client->patch($path, %options);
delete
my $res = $client->delete($path, %options);
head
my $res = $client->head($path, %options);
options
my $res = $client->options($path, %options);
Request Options
- headers => { ... }
-
Additional headers for this request.
- query => { ... }
-
Query string parameters. Appended to the path.
- json => { ... }
-
JSON request body. Automatically sets Content-Type to application/json.
- form => { ... }
-
Form-encoded request body. Sets Content-Type to application/x-www-form-urlencoded.
- body => $bytes
-
Raw request body bytes.
SESSION METHODS
cookies
my $hashref = $client->cookies;
Returns all current session cookies.
cookie
my $value = $client->cookie('session_id');
Returns a specific cookie value.
set_cookie
$client->set_cookie('theme', 'dark');
Manually sets a cookie.
clear_cookies
$client->clear_cookies;
Clears all session cookies.
WEBSOCKET
websocket
# Callback style (auto-close)
$client->websocket('/ws', sub {
my ($ws) = @_;
$ws->send_text('hello');
is $ws->receive_text, 'echo: hello';
});
# Explicit style
my $ws = $client->websocket('/ws');
$ws->send_text('hello');
is $ws->receive_text, 'echo: hello';
$ws->close;
See PAGI::Test::WebSocket for the WebSocket connection API.
SSE (Server-Sent Events)
sse
# Callback style (auto-close)
$client->sse('/events', sub {
my ($sse) = @_;
my $event = $sse->receive_event;
is $event->{data}, 'connected';
});
# Explicit style
my $sse = $client->sse('/events');
my $event = $sse->receive_event;
$sse->close;
See PAGI::Test::SSE for the SSE connection API.
LIFESPAN
start
$client->start;
Triggers lifespan.startup. Only needed if lifespan = 1> was passed to the constructor.
stop
$client->stop;
Triggers lifespan.shutdown.
state
my $state = $client->state;
Returns the shared state hashref from lifespan.
run
PAGI::Test::Client->run($app, sub {
my ($client) = @_;
# ... tests ...
});
Class method that creates a client with lifespan enabled, calls start, runs your callback, then calls stop. Exceptions propagate.
SEE ALSO
PAGI::Test::Response, PAGI::Test::WebSocket, PAGI::Test::SSE