Chandra
view release on metacpan or search on metacpan
t/34_socket_edge.t view on Meta::CPAN
my $conn1 = Chandra::Socket::Connection->new(socket => $s1, name => 'reply-sender');
my $conn2 = Chandra::Socket::Connection->new(socket => $s2, name => 'reply-receiver');
my $result = $conn1->reply({ channel => 'query', _id => 42 }, { answer => 'yes' });
ok($result, 'reply with _id succeeds');
select(undef, undef, undef, 0.05);
my @msgs = $conn2->recv;
is(scalar @msgs, 1, 'reply received');
is($msgs[0]->{_reply_to}, 42, 'reply has correct _reply_to');
is($msgs[0]->{data}{answer}, 'yes', 'reply data correct');
$conn1->close;
$conn2->close;
}
# === Connection reply with undef original returns 0 ===
SKIP: {
skip 'AF_UNIX socketpair not available on Windows', 1 if $is_win32;
use Socket;
socketpair(my $s1, my $s2, AF_UNIX, SOCK_STREAM, 0) or die "socketpair: $!";
$s1->blocking(0);
my $conn = Chandra::Socket::Connection->new(socket => $s1, name => 'reply-nil');
my $result = $conn->reply(undef, { data => 1 });
is($result, 0, 'reply with undef original returns 0');
$conn->close;
close $s2;
}
# === Connection send with extra fields ===
SKIP: {
skip 'AF_UNIX socketpair not available on Windows', 2 if $is_win32;
use Socket;
socketpair(my $s1, my $s2, AF_UNIX, SOCK_STREAM, 0) or die "socketpair: $!";
$s1->blocking(0);
$s2->blocking(0);
my $conn1 = Chandra::Socket::Connection->new(socket => $s1, name => 'extra');
my $conn2 = Chandra::Socket::Connection->new(socket => $s2, name => 'extra-recv');
$conn1->send('test', { val => 1 }, { _id => 99, custom => 'field' });
select(undef, undef, undef, 0.05);
my @msgs = $conn2->recv;
is($msgs[0]->{_id}, 99, 'extra _id field preserved');
is($msgs[0]->{custom}, 'field', 'custom extra field preserved');
$conn1->close;
$conn2->close;
}
# === encode_frame / decode_frames with empty data ===
{
my $frame = Chandra::Socket::Connection->encode_frame({ channel => 'empty', data => {} });
my @decoded = Chandra::Socket::Connection->decode_frames($frame);
is(scalar @decoded, 1, 'empty data decoded');
is_deeply($decoded[0]->{data}, {}, 'empty data preserved');
}
# === encode_frame / decode_frames with unicode ===
{
my $frame = Chandra::Socket::Connection->encode_frame({ channel => 'unicode', data => { text => "æ¥æ¬èª" } });
my @decoded = Chandra::Socket::Connection->decode_frames($frame);
is($decoded[0]->{data}{text}, "æ¥æ¬èª", 'unicode preserved through encode/decode');
}
# === decode_frames with empty buffer ===
{
my @decoded = Chandra::Socket::Connection->decode_frames('');
is(scalar @decoded, 0, 'empty buffer returns no messages');
}
# === decode_frames with incomplete length header ===
{
my @decoded = Chandra::Socket::Connection->decode_frames("\x00\x00");
is(scalar @decoded, 0, 'incomplete header returns no messages');
}
# === Hub send_to nonexistent client returns 0 ===
{
my $name = "test-send-nonexist-$$";
my $hub = Chandra::Socket::Hub->new(name => $name);
my $result = $hub->send_to('ghost', 'test', { data => 1 });
is($result, 0, 'send_to nonexistent client returns 0');
$hub->close;
}
# === Hub on() returns self for chaining ===
{
my $name = "test-on-chain-$$";
my $hub = Chandra::Socket::Hub->new(name => $name);
my $ret = $hub->on('test', sub { });
is($ret, $hub, 'on() returns self');
$hub->close;
}
# === Hub on_connect returns self ===
{
my $name = "test-onconn-$$";
my $hub = Chandra::Socket::Hub->new(name => $name);
my $ret = $hub->on_connect(sub { });
is($ret, $hub, 'on_connect returns self');
$hub->close;
}
# === Hub on_disconnect returns self ===
{
my $name = "test-ondisc-$$";
my $hub = Chandra::Socket::Hub->new(name => $name);
my $ret = $hub->on_disconnect(sub { });
is($ret, $hub, 'on_disconnect returns self');
$hub->close;
}
# === Hub broadcast returns self ===
{
my $name = "test-bc-self-$$";
my $hub = Chandra::Socket::Hub->new(name => $name);
my $ret = $hub->broadcast('test', {});
is($ret, $hub, 'broadcast returns self');
$hub->close;
}
# === Hub poll returns self ===
( run in 1.645 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )