Permalink
Browse files

Support nested multibulk objects.

Test with a multibulk response from EXEC.
  • Loading branch information...
1 parent bab9073 commit 10b21fb06b2caadbe074d5032a68858cb441fac6 @jdavisp3 jdavisp3 committed Oct 8, 2011
Showing with 64 additions and 0 deletions.
  1. +1 −0 src/eredis_parser.erl
  2. +45 −0 test/eredis_parser_tests.erl
  3. +18 −0 test/eredis_tests.erl
View
1 src/eredis_parser.erl
@@ -171,6 +171,7 @@ do_parse_multibulk(Count, Data, Acc) ->
%% BULK
%%
+parse_bulk(<<$*, _Rest/binary>> = Data) -> parse_multibulk(Data);
parse_bulk(<<$+, Data/binary>>) -> parse_simple(Data);
parse_bulk(<<$-, Data/binary>>) -> parse_simple(Data);
parse_bulk(<<$:, Data/binary>>) -> parse_simple(Data);
View
45 test/eredis_parser_tests.erl
@@ -13,6 +13,27 @@
parse_multibulk/1, parse_multibulk/2]).
+% parse a binary one byte at a time
+one_byte_parse(B) ->
+ one_byte_parse(init(), B).
+
+one_byte_parse(S, <<>>) ->
+ parse(S, <<>>);
+one_byte_parse(S, <<Byte>>) ->
+ parse(S, <<Byte>>);
+one_byte_parse(S, <<Byte, B/binary>>) ->
+ case parse(S, <<Byte>>) of
+ {continue, NewState} ->
+ one_byte_parse(NewState, B);
+ {ok, Value, Rest, NewState} ->
+ {ok, Value, <<Rest/binary, B/binary>>, NewState};
+ {error, Err, Rest, NewState} ->
+ {error, Err, <<Rest/binary, B/binary>>, NewState};
+ Other ->
+ Other
+ end.
+
+
parse_bulk_test() ->
B = <<"$3\r\nbar\r\n">>,
?assertEqual({ok, <<"bar">>, #pstate{}}, parse(#pstate{}, B)).
@@ -135,6 +156,30 @@ multibulk_parse_test() ->
B = <<"*3\r\n$1\r\n1\r\n$1\r\n2\r\n$1\r\n3\r\n">>,
?assertEqual({ok, [<<"1">>, <<"2">>, <<"3">>], #pstate{}}, parse(init(), B)).
+multibulk_one_byte_parse_test() ->
+ %% [{1, 1}, {2, 2}, {3, 3}]
+ B = <<"*3\r\n$1\r\n1\r\n$1\r\n2\r\n$1\r\n3\r\n">>,
+ ?assertEqual({ok, [<<"1">>, <<"2">>, <<"3">>], #pstate{}},
+ one_byte_parse(B)).
+
+nested_multibulk_test() ->
+ %% [[1, 2], [3, 4]]
+ B = <<"*2\r\n*2\r\n$1\r\n1\r\n$1\r\n2\r\n*2\r\n$1\r\n3\r\n$1\r\n4\r\n">>,
+ ?assertEqual({ok, [[<<"1">>, <<"2">>], [<<"3">>, <<"4">>]], <<>>},
+ parse_multibulk(B)).
+
+nested_multibulk_parse_test() ->
+ %% [[1, 2], [3, 4]]
+ B = <<"*2\r\n*2\r\n$1\r\n1\r\n$1\r\n2\r\n*2\r\n$1\r\n3\r\n$1\r\n4\r\n">>,
+ ?assertEqual({ok, [[<<"1">>, <<"2">>], [<<"3">>, <<"4">>]], #pstate{}},
+ parse(init(), B)).
+
+nested_multibulk_one_byte_parse_test() ->
+ %% [[1, 2], [3, 4]]
+ B = <<"*2\r\n*2\r\n$1\r\n1\r\n$1\r\n2\r\n*2\r\n$1\r\n3\r\n$1\r\n4\r\n">>,
+ ?assertEqual({ok, [[<<"1">>, <<"2">>], [<<"3">>, <<"4">>]], #pstate{}},
+ one_byte_parse(B)).
+
multibulk_split_parse_test() ->
%% [{1, 1}, {2, 2}, {3, 3}]
B1 = <<"*3\r\n$1\r\n1\r\n$1">>,
View
18 test/eredis_tests.erl
@@ -34,6 +34,24 @@ mset_mget_test() ->
?assertEqual({ok, ExpectedResult}, eredis:q(C, ["MGET" | Keys])),
?assertMatch({ok, _}, eredis:q(C, ["DEL" | Keys])).
+exec_test() ->
+ C = c(),
+
+ ?assertMatch({ok, _}, eredis:q(C, ["LPUSH", "k1", "b"])),
+ ?assertMatch({ok, _}, eredis:q(C, ["LPUSH", "k1", "a"])),
+ ?assertMatch({ok, _}, eredis:q(C, ["LPUSH", "k2", "c"])),
+
+ ?assertEqual({ok, <<"OK">>}, eredis:q(C, ["MULTI"])),
+ ?assertEqual({ok, <<"QUEUED">>}, eredis:q(C, ["LRANGE", "k1", "0", "-1"])),
+ ?assertEqual({ok, <<"QUEUED">>}, eredis:q(C, ["LRANGE", "k2", "0", "-1"])),
+
+ ExpectedResult = [[<<"a">>, <<"b">>], [<<"c">>]],
+
+ ?assertEqual({ok, ExpectedResult}, eredis:q(C, ["EXEC"])),
+
+ ?assertMatch({ok, _}, eredis:q(C, ["DEL", "k1", "k2"])).
+
+
c() ->
Res = eredis:start_link(),
?assertMatch({ok, _}, Res),

0 comments on commit 10b21fb

Please sign in to comment.