use Test::More 0.88;
use strict; use warnings FATAL => 'all';
use POE;
use_ok( 'POEx::IRC::Client::Lite' );
my $got = {};
my $expected = {
'client connected' => 1,
'client sent USER' => 1,
'client sent NICK' => 1,
'client NICK looks ok' => 1,
'client got SNACK' => 1,
'client got public_msg' => 1,
'client got ctcp_version' => 1,
'client sent arbitrary' => 1,
'client sent QUIT' => 1,
'client sent correct MODE' => 2,
};
alarm 60;
POE::Session->create(
package_states => [
main => [ qw/
_start
check
shutdown
ircsock_registered
ircsock_listener_created
ircsock_listener_open
ircsock_input
client_irc_snack
client_irc_public_msg
client_irc_ctcp_version
send_quit
/ ],
],
);
$poe_kernel->run;
sub _start {
my ($k, $heap) = @_[KERNEL, HEAP];
$k->sig(ALRM => shutdown => 'timeout');
$heap->{serv} = POEx::IRC::Backend->new->spawn;
$k->post( $heap->{serv}->session_id, 'register' );
$k->delay( check => 0.5 );
}
sub check {
my ($k, $heap) = @_[KERNEL, HEAP];
if (keys %$got == keys %$expected) {
$k->yield( 'shutdown' );
return
}
$k->delay( check => 0.5 );
}
sub shutdown {
my ($k, $heap) = @_[KERNEL, HEAP];
$k->alarm_remove_all;
$heap->{serv}->shutdown;
$heap->{client}->stop;
fail "Timed out" if $_[ARG0];
}
### "server" bits ->
sub ircsock_registered {
my ($k, $heap) = @_[KERNEL, HEAP];
my $backend = $_[ARG0];
pass("ircsock_registered");
$backend->create_listener(
bindaddr => '127.0.0.1',
port => 0,
);
}
sub ircsock_listener_created {
my ($k, $heap) = @_[KERNEL, HEAP];
my $listener = $_[ARG0];
pass("Got listener_created");
note("Starting client");
$heap->{client} = POEx::IRC::Client::Lite->new(
event_prefix => 'client_',
server => $listener->addr,
port => $listener->port,
nick => 'test',
username => 'user',
);
$heap->{client}->connect;
}
sub ircsock_listener_open {
my ($k, $heap) = @_[KERNEL, HEAP];
my ($conn, $listener) = @_[ARG0, ARG1];
$got->{'client connected'}++;
## Fire some traffic at the client.
$heap->{serv}->send(
{
prefix => 'server',
command => 'snack',
params => [ 'things and stuff' ],
},
$conn->wheel_id
);
$heap->{serv}->send(
{
prefix => 'server',
command => 'privmsg',
params => [ '#chan', 'some message' ],
},
$conn->wheel_id
);
$heap->{serv}->send(
{
prefix => 'server',
command => 'privmsg',
params => [ 'test', ctcp_quote('VERSION') ]
},
$conn->wheel_id
);
}
sub ircsock_input {
my ($k, $heap) = @_[KERNEL, HEAP];
my ($conn, $ev) = @_[ARG0, ARG1];
if ($ev->command eq 'USER') {
$got->{'client sent USER'}++
}
if ($ev->command eq 'NICK') {
$got->{'client sent NICK'}++;
$got->{'client NICK looks ok'}++
if $ev->params->[0] eq 'test';
}
if ($ev->command eq 'NONSENSE') {
$got->{'client sent arbitrary'}++;
}
if ($ev->command eq 'QUIT') {
$got->{'client sent QUIT'}++;
}
if ($ev->command eq 'MODE') {
$got->{'client sent correct MODE'}++
if $ev->params->[0] eq '#target'
and $ev->params->[1] eq '+o-o avenj avenj';
}
}
### our client's events ->
## An arbitrary command:
sub client_irc_snack {
my ($k, $heap) = @_[KERNEL, HEAP];
my $ev = $_[ARG0];
$got->{'client got SNACK'}++;
$heap->{client}->send(
{
command => 'nonsense',
}
);
## IRC::Mode::Set
$heap->{client}->mode(
'#target',
IRC::Mode::Set->new(
mode_string => '+o-o avenj avenj',
)
);
## Stringy mode
$heap->{client}->mode(
'#target',
'+o-o avenj avenj'
);
}
## pubmsg parser:
sub client_irc_public_msg {
my ($k, $heap) = @_[KERNEL, HEAP];
my $ev = $_[ARG0];
$got->{'client got public_msg'}++;
}
## ctcp parser:
sub client_irc_ctcp_version {
my ($k, $heap) = @_[KERNEL, HEAP];
my $ev = $_[ARG0];
$got->{'client got ctcp_version'}++;
$k->delay( 'send_quit' => 1 );
}
sub send_quit {
my ($k, $heap) = @_[KERNEL, HEAP];
$heap->{client}->disconnect('bye');
}
for my $t (keys %$expected) {
ok( defined $got->{$t}, "have result for '$t'" );
cmp_ok( $got->{$t}, '==', $expected->{$t},
"result for '$t' looks ok"
);
}
done_testing;