You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 regels
2.6 KiB

5 jaren geleden
  1. % This file is part of Jiffy released under the MIT license.
  2. % See the LICENSE file for more information.
  3. -module(jiffy_18_decode_levels_tests).
  4. -include_lib("eunit/include/eunit.hrl").
  5. decode_levels_test_() ->
  6. MaxOptMaxLevels = 4,
  7. Cases = [
  8. <<"{\"foo\":\"bar\"}">>,
  9. <<"{\"foo\":[\"bar\"]}">>,
  10. <<"[[[[]],\"foo\"], [\"bar\", []], [\"baz\"], [[], 1]]">>,
  11. <<"{\"foo\":{},\"bar\":{\"baz\":[1,2,3], \"foo2\":{}}}">>
  12. ],
  13. {"Test max_levels", lists:map(fun(Json) ->
  14. [
  15. begin
  16. EJson = jiffy:decode(Json, [{max_levels, MaxLevels} | Opts]),
  17. FullEJson = to_full_json(EJson, MaxLevels, Opts),
  18. ?_assertEqual(jiffy:decode(Json, Opts), FullEJson)
  19. end || MaxLevels <- lists:seq(1, MaxOptMaxLevels), Opts <- generate_options_groups()]
  20. end, Cases)}.
  21. -ifndef(JIFFY_NO_MAPS).
  22. generate_options_groups() -> generate_options_groups([return_maps, copy_strings]).
  23. -else.
  24. generate_options_groups() -> generate_options_groups([copy_strings]).
  25. -endif.
  26. generate_options_groups(AvailableOptions) ->
  27. generate_options_groups(AvailableOptions, [[]]).
  28. generate_options_groups([], Acc) ->
  29. Acc;
  30. generate_options_groups([Option | AvailableOptions], Acc) ->
  31. generate_options_groups(AvailableOptions, [[Option | Group] || Group <- Acc] ++ Acc).
  32. to_full_json(Val, MaxDepth, DecodeOptions) ->
  33. to_full_json(Val, 0, MaxDepth, DecodeOptions).
  34. to_full_json(_Val, Depth, MaxDepth, _DecodeOptions) when Depth > MaxDepth ->
  35. error(too_deep);
  36. to_full_json({json, ValueBin}, Depth, MaxDepth, DecodeOptions) ->
  37. MaxDepth = Depth,
  38. true = is_binary(ValueBin),
  39. ByteSize = byte_size(ValueBin),
  40. case lists:member(copy_strings, DecodeOptions) of
  41. true ->
  42. ByteSize = binary:referenced_byte_size(ValueBin);
  43. _ ->
  44. true = ByteSize < binary:referenced_byte_size(ValueBin)
  45. end,
  46. jiffy:decode(ValueBin, DecodeOptions);
  47. to_full_json({Pairs}, Depth, MaxDepth, DecodeOptions) when is_list(Pairs) ->
  48. {[{K, to_full_json(V, Depth+1, MaxDepth, DecodeOptions)} || {K, V} <- Pairs]};
  49. to_full_json(Vals, Depth, MaxDepth, DecodeOptions) when is_list(Vals) ->
  50. [to_full_json(V, Depth+1, MaxDepth, DecodeOptions) || V <- Vals];
  51. to_full_json(Val, Depth, MaxDepth, DecodeOptions) ->
  52. maybe_map(Val, Depth, MaxDepth, DecodeOptions).
  53. -ifndef(JIFFY_NO_MAPS).
  54. maybe_map(Obj, Depth, MaxDepth, DecodeOptions) when is_map(Obj) ->
  55. maps:map(fun(_K, V) -> to_full_json(V, Depth+1, MaxDepth, DecodeOptions) end, Obj);
  56. maybe_map(Val, _Depth, _MaxDepth, _DecodeOptions) ->
  57. Val.
  58. -else.
  59. maybe_map(Val, _Depth, _MaxDepth, _DecodeOptions) ->
  60. Val.
  61. -endif.