Skip to content

Instantly share code, notes, and snippets.

@Grinnz Grinnz/protocol.t
Last active Feb 8, 2019

Embed
What would you like to do?
Mojo::Redis::Protocol test file
use Mojo::Base -strict;
use Test::More;
use Mojo::Redis::Protocol;
my $protocol = Mojo::Redis::Protocol->new;
# Protocol error
ok !eval { $protocol->parse("\@") }, 'protocol error';
like $@, qr/Unknown message type/, 'right error';
is_deeply [$protocol->parse('')], [], 'state not reset';
$protocol = Mojo::Redis::Protocol->new;
# Simple test
is_deeply [$protocol->parse("+test\r\n")], [{type => '+', data => 'test'}],
'simple message';
is_deeply [$protocol->parse('')], [], 'queue is empty';
is_deeply [$protocol->parse(":1\r\n")], [{type => ':', data => 1}],
'simple number';
is_deeply [$protocol->parse(join "\r\n", '$4', pack('C4', 0..3), '')],
[{type => '$', data => "\0\1\2\3"}], 'binary data';
is_deeply [$protocol->parse('-tes')], [], 'incomplete message';
is_deeply [$protocol->parse("t2\r\n")], [{type => '-', data => 'test2'}],
'chunked string';
is_deeply [$protocol->parse('+test')], [], 'incomplete message';
is_deeply [$protocol->parse("1\r\n-test2\r\n")],
[{type => '+', data => 'test1'}, {type => '-', data => 'test2'}],
'first stick message';
is_deeply [$protocol->parse("+OK\r\n-ERROR\r\n")],
[{type => '+', data => 'OK'}, {type => '-', data => 'ERROR'}],
'pipelined status messages';
# Bulk message
is_deeply [$protocol->parse("\$4\r\ntest\r\n")],
[{type => '$', data => 'test'}], 'simple bulk message';
is_deeply [$protocol->parse("\$5\r\ntes")], [], 'incomplete message';
is_deeply [$protocol->parse("t2\r\n")], [{type => '$', data => 'test2'}],
'chunked bulk message';
my ($message) = $protocol->parse("\$-1\r\n");
ok defined($message) && !defined($message->{data}), 'nil bulk message';
is_deeply [$protocol->parse("\$4\r\ntest\r\n+OK")],
[{type => '$', data => 'test'}], 'first chunked message';
is_deeply [$protocol->parse("\r\n")], [{type => '+', data => 'OK'}],
'second chunked message';
is_deeply [$protocol->parse("\$3\r\nok1\r\n\$3\r\nok2\r\n")],
[{type => '$', data => 'ok1'}, {type => '$', data => 'ok2'}],
'pipelined bulk message';
# Multi bulk message
is_deeply [$protocol->parse("*1\r\n\$4\r\ntest\r\n")],
[{type => '*', data => ['test']}], 'simple multibulk message';
is_deeply [$protocol->parse("*3\r\n\$5\r\ntest1\r\n")], [],
'incomplete message';
is_deeply [$protocol->parse("\$5\r\ntest2\r\n")], [],
'incomplete message';
is_deeply [$protocol->parse("\$5\r\ntest3\r\n")],
[{type => '*', data => ['test1','test2','test3']}],
'multi argument multi-bulk message';
is_deeply [$protocol->parse("*0\r\n")], [{type => '*', data => []}],
'multi-bulk empty result';
($message) = $protocol->parse("*-1\r\n");
ok defined($message) && !defined($message->{data}),
'multi-bulk nil result';
is_deeply [$protocol->parse("*2\r\n+OK\r\n\$4\r\ntest\r\n")],
[{type => '*', data => ['OK','test']}], 'multi-bulk with status items';
is_deeply [$protocol->parse("*1\r\n\$4\r\ntest\r\n+OK")],
[{type => '*', data => ['test']}], 'multi-bulk and partial status';
is_deeply [$protocol->parse("\r\n")], [{type => '+', data => 'OK'}],
'status message';
is_deeply [$protocol->parse(join "\r\n", qw(*2 $3 ok1 $3 ok2 *1 $3 ok3))],
[{type => '*', data => ['ok1','ok2']},{type => '*', data => ['ok3']}],
'pipelined multi-bulk';
# Encode message
is $protocol->encode({type => '+', data => 'OK'}), "+OK\r\n",
'encode status';
is $protocol->encode({type => '-', data => 'ERROR'}), "-ERROR\r\n",
'encode error';
is $protocol->encode({type => ':', data => '5'}), ":5\r\n", 'encode integer';
# Encode bulk message
is $protocol->encode({type => '$', data => 'test'}), "\$4\r\ntest\r\n",
'encode bulk';
is $protocol->encode({type => '$', data => "\0\r\n"}), "\$3\r\n\0\r\n\r\n",
'encode binary bulk';
is $protocol->encode({type => '$', data => undef}), "\$-1\r\n",
'encode nil bulk';
# Encode multi-bulk
is $protocol->encode({type => '*', data => [{type => '$', data => 'test'}]}),
join("\r\n", ('*1', '$4', 'test'), ''),
'encode multi-bulk';
is $protocol->encode(
{ type => '*',
data => [
{type => '$', data => 'test1'}, {type => '$', data => 'test2'}
]
}
),
join("\r\n", ('*2', '$5', 'test1', '$5', 'test2'), ''),
'encode multi-bulk';
is $protocol->encode({type => '*', data => []}), "\*0\r\n",
'encode empty multi-bulk';
is $protocol->encode({type => '*', data => undef}), "\*-1\r\n",
'encode nil multi-bulk';
is $protocol->encode(
{ type => '*',
data => [
{type => '$', data => 'foo'},
{type => '$', data => undef},
{type => '$', data => 'bar'}
]
}
),
join("\r\n", ('*3', '$3', 'foo', '$-1', '$3', 'bar'), ''),
'encode multi-bulk with nil element';
# Charset encode
$protocol->encoding('UTF-8');
is $protocol->encode({type => '$', data => ''}), "\$3\r\n\xE2\x98\x83\r\n",
'UTF-8 encode';
is_deeply [$protocol->parse("\$3\r\n\xE2\x98\x83\r\n")],
[{type => '$', data => ''}], 'UTF-8 decode';
$protocol->encoding('UTF-16BE');
is $protocol->encode({type => '$', data => '☀ഊ'}), "\$4\r\n\x26\x00\x0D\x0A\r\n",
'UTF-16BE encode';
is_deeply [$protocol->parse("\$4\r\n\x26\x00\x0D\x0A\r\n")],
[{type => '$', data => '☀ഊ'}], 'UTF-16BE decode';
is $protocol->encode({type => '+', data => "\xB0"}), "+\xB0\r\n",
'no charset encoding';
$protocol->encoding('UTF-8');
is_deeply [$protocol->parse("+\xC2\xB0\r\n")],
[{type => '+', data => "\xC2\xB0"}], 'no charset decoding';
done_testing;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.