add incomplete_handler and tests

This commit is contained in:
alisdair sullivan 2013-03-04 23:13:23 -08:00
parent ca89432e7a
commit 2d7b690a91
4 changed files with 86 additions and 38 deletions

View file

@ -9,5 +9,6 @@
ignored_bad_escapes = false, ignored_bad_escapes = false,
explicit_end = false, explicit_end = false,
pre_encode = false, pre_encode = false,
error_handler = false error_handler = false,
incomplete_handler = false
}). }).

View file

@ -105,34 +105,42 @@ decoder(Handler, State, Config) ->
-ifndef(incomplete). -ifndef(incomplete).
-define(incomplete(State, Rest, Handler, Stack, Config),
{incomplete, fun(Stream) when is_binary(Stream) ->
State(<<Rest/binary, Stream/binary>>, Handler, Stack, Config)
; (end_stream) ->
case State(<<Rest/binary, <<" ">>/binary>>,
Handler,
Stack,
Config#config{explicit_end=false}) of
{incomplete, _} -> ?error(State, Rest, Handler, Stack, Config)
; Events -> Events
end
end
}
).
-define(incomplete(State, Rest, Handler, Acc, Stack, Config), -define(incomplete(State, Rest, Handler, Acc, Stack, Config),
{incomplete, fun(Stream) when is_binary(Stream) -> case Config#config.incomplete_handler of
State(<<Rest/binary, Stream/binary>>, Handler, Acc, Stack, Config) false ->
; (end_stream) -> {incomplete, fun(Stream) when is_binary(Stream) ->
case State(<<Rest/binary, <<" ">>/binary>>, State(<<Rest/binary, Stream/binary>>, Handler, Acc, Stack, Config)
Handler, ; (end_stream) ->
Acc, case State(<<Rest/binary, <<" ">>/binary>>,
Stack, Handler,
Config#config{explicit_end=false}) of Acc,
{incomplete, _} -> ?error(State, Rest, Handler, Acc, Stack, Config) Stack,
; Events -> Events Config#config{explicit_end=false}) of
{incomplete, _} -> ?error(State, Rest, Handler, Acc, Stack, Config)
; Events -> Events
end
end end
end };
} F -> F(Rest, {decoder, State, Handler, Acc, Stack}, Config)
end
).
-define(incomplete(State, Rest, Handler, Stack, Config),
case Config#config.incomplete_handler of
false ->
{incomplete, fun(Stream) when is_binary(Stream) ->
State(<<Rest/binary, Stream/binary>>, Handler, Stack, Config)
; (end_stream) ->
case State(<<Rest/binary, <<" ">>/binary>>,
Handler,
Stack,
Config#config{explicit_end=false}) of
{incomplete, _} -> ?error(State, Rest, Handler, Stack, Config)
; Events -> Events
end
end
};
F -> F(Rest, {decoder, State, Handler, null, Stack}, Config)
end
). ).
-endif. -endif.
@ -2041,5 +2049,15 @@ custom_error_handler_test_() ->
]. ].
custom_incomplete_handler_test_() ->
Decode = fun(JSON, Config) -> start(JSON, {jsx, []}, [], jsx_utils:parse_config(Config)) end,
[
{"custom incomplete handler", ?_assertError(
badarg,
Decode(<<>>, [{incomplete_handler, fun(_, _, _) -> erlang:error(badarg) end}])
)}
].
-endif. -endif.

View file

@ -49,18 +49,22 @@ parser(Handler, State, Config) ->
-ifndef(incomplete). -ifndef(incomplete).
-define(incomplete(State, Handler, Stack, Config), -define(incomplete(State, Handler, Stack, Config),
{incomplete, fun(end_stream) -> case Config#config.incomplete_handler of
case State([end_json], false ->
Handler, {incomplete, fun(end_stream) ->
Stack, case State([end_json],
Config) of Handler,
{incomplete, _} -> ?error(State, [], Handler, Stack, Config) Stack,
; Events -> Events Config) of
{incomplete, _} -> ?error(State, [], Handler, Stack, Config)
; Events -> Events
end
; (Tokens) ->
State(Tokens, Handler, Stack, Config)
end end
; (Tokens) -> };
State(Tokens, Handler, Stack, Config) F -> F([], {parser, State, Handler, Stack}, Config)
end end
}
). ).
-endif. -endif.
@ -236,4 +240,13 @@ custom_error_handler_test_() ->
]. ].
custom_incomplete_handler_test_() ->
[
{"custom incomplete handler", ?_assertError(
badarg,
parse([], [{incomplete_handler, fun(_, _, _) -> erlang:error(badarg) end}])
)}
].
-endif. -endif.

View file

@ -76,6 +76,11 @@ parse_config([{error_handler, ErrorHandler}|Rest] = Options, Config) when is_fun
false -> parse_config(Rest, Config#config{error_handler=ErrorHandler}) false -> parse_config(Rest, Config#config{error_handler=ErrorHandler})
; _ -> erlang:error(badarg, [Options, Config]) ; _ -> erlang:error(badarg, [Options, Config])
end; end;
parse_config([{incomplete_handler, IncompleteHandler}|Rest] = Options, Config) when is_function(IncompleteHandler, 3) ->
case Config#config.incomplete_handler of
false -> parse_config(Rest, Config#config{incomplete_handler=IncompleteHandler})
; _ -> erlang:error(badarg, [Options, Config])
end;
%% deprecated flags %% deprecated flags
parse_config([{pre_encoder, Encoder}|Rest] = Options, Config) when is_function(Encoder, 1) -> parse_config([{pre_encoder, Encoder}|Rest] = Options, Config) when is_function(Encoder, 1) ->
case Config#config.pre_encode of case Config#config.pre_encode of
@ -631,6 +636,17 @@ config_test_() ->
{error_handler, fun(_) -> false end} {error_handler, fun(_) -> false end}
]) ])
)}, )},
{"incomplete_handler flag", ?_assertEqual(
#config{incomplete_handler=fun ?MODULE:fake_error_handler/3},
parse_config([{incomplete_handler, fun ?MODULE:fake_error_handler/3}])
)},
{"two incomplete_handlers defined", ?_assertError(
badarg,
parse_config([
{incomplete_handler, fun(_) -> true end},
{incomplete_handler, fun(_) -> false end}
])
)},
{"bad option flag", ?_assertError(badarg, parse_config([error]))} {"bad option flag", ?_assertError(badarg, parse_config([error]))}
]. ].