|
|
@ -0,0 +1,71 @@ |
|
|
|
% This file is part of Jiffy released under the MIT license. |
|
|
|
% See the LICENSE file for more information. |
|
|
|
|
|
|
|
-module(jiffy_18_decode_levels_tests). |
|
|
|
|
|
|
|
-include_lib("eunit/include/eunit.hrl"). |
|
|
|
|
|
|
|
decode_levels_test_() -> |
|
|
|
MaxOptMaxLevels = 4, |
|
|
|
Cases = [ |
|
|
|
<<"{\"foo\":\"bar\"}">>, |
|
|
|
<<"{\"foo\":[\"bar\"]}">>, |
|
|
|
<<"[[[[]],\"foo\"], [\"bar\", []], [\"baz\"], [[], 1]]">>, |
|
|
|
<<"{\"foo\":{},\"bar\":{\"baz\":[1,2,3], \"foo2\":{}}}">> |
|
|
|
], |
|
|
|
{"Test max_levels", lists:map(fun(Json) -> |
|
|
|
[ |
|
|
|
begin |
|
|
|
EJson = jiffy:decode(Json, [{max_levels, MaxLevels} | Opts]), |
|
|
|
FullEJson = to_full_json(EJson, MaxLevels, Opts), |
|
|
|
?_assertEqual(jiffy:decode(Json, Opts), FullEJson) |
|
|
|
end || MaxLevels <- lists:seq(1, MaxOptMaxLevels), Opts <- generate_options_groups()] |
|
|
|
end, Cases)}. |
|
|
|
|
|
|
|
|
|
|
|
-ifndef(JIFFY_NO_MAPS). |
|
|
|
generate_options_groups() -> generate_options_groups([return_maps, copy_strings]). |
|
|
|
-else. |
|
|
|
generate_options_groups() -> generate_options_groups([copy_strings]). |
|
|
|
-endif. |
|
|
|
|
|
|
|
generate_options_groups(AvailableOptions) -> |
|
|
|
generate_options_groups(AvailableOptions, [[]]). |
|
|
|
generate_options_groups([], Acc) -> |
|
|
|
Acc; |
|
|
|
generate_options_groups([Option | AvailableOptions], Acc) -> |
|
|
|
generate_options_groups(AvailableOptions, [[Option | Group] || Group <- Acc] ++ Acc). |
|
|
|
|
|
|
|
|
|
|
|
to_full_json(Val, MaxDepth, DecodeOptions) -> |
|
|
|
to_full_json(Val, 0, MaxDepth, DecodeOptions). |
|
|
|
to_full_json(_Val, Depth, MaxDepth, _DecodeOptions) when Depth > MaxDepth -> |
|
|
|
error(too_deep); |
|
|
|
to_full_json({json, ValueBin}, Depth, MaxDepth, DecodeOptions) -> |
|
|
|
MaxDepth = Depth, |
|
|
|
true = is_binary(ValueBin), |
|
|
|
ByteSize = byte_size(ValueBin), |
|
|
|
case lists:member(copy_strings, DecodeOptions) of |
|
|
|
true -> |
|
|
|
ByteSize = binary:referenced_byte_size(ValueBin); |
|
|
|
_ -> |
|
|
|
true = ByteSize < binary:referenced_byte_size(ValueBin) |
|
|
|
end, |
|
|
|
jiffy:decode(ValueBin, DecodeOptions); |
|
|
|
to_full_json({Pairs}, Depth, MaxDepth, DecodeOptions) when is_list(Pairs) -> |
|
|
|
{[{K, to_full_json(V, Depth+1, MaxDepth, DecodeOptions)} || {K, V} <- Pairs]}; |
|
|
|
to_full_json(Vals, Depth, MaxDepth, DecodeOptions) when is_list(Vals) -> |
|
|
|
[to_full_json(V, Depth+1, MaxDepth, DecodeOptions) || V <- Vals]; |
|
|
|
to_full_json(Val, Depth, MaxDepth, DecodeOptions) -> |
|
|
|
maybe_map(Val, Depth, MaxDepth, DecodeOptions). |
|
|
|
|
|
|
|
-ifndef(JIFFY_NO_MAPS). |
|
|
|
maybe_map(Obj, Depth, MaxDepth, DecodeOptions) when is_map(Obj) -> |
|
|
|
maps:map(fun(_K, V) -> to_full_json(V, Depth+1, MaxDepth, DecodeOptions) end, Obj); |
|
|
|
maybe_map(Val, _Depth, _MaxDepth, _DecodeOptions) -> |
|
|
|
Val. |
|
|
|
-else. |
|
|
|
maybe_map(Val, _Depth, _MaxDepth, _DecodeOptions) -> |
|
|
|
Val. |
|
|
|
-endif. |
|
|
|
|