Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

153 řádky
3.0 KiB

  1. % This file is part of Jiffy released under the MIT license.
  2. % See the LICENSE file for more information.
  3. -module(jiffy_tests).
  4. -ifdef(JIFFY_DEV).
  5. -include_lib("proper/include/proper.hrl").
  6. -include_lib("eunit/include/eunit.hrl").
  7. proper_test_() ->
  8. PropErOpts = [
  9. {to_file, user},
  10. {max_size, 15},
  11. {numtests, 1000}
  12. ],
  13. {timeout, 3600, ?_assertEqual([], proper:module(jiffy_tests, PropErOpts))}.
  14. prop_encode_decode() ->
  15. ?FORALL(Data, json(),
  16. begin
  17. %io:format(standard_error, "Data: ~p~n", [Data]),
  18. Data == jiffy:decode(jiffy:encode(Data))
  19. end
  20. ).
  21. -ifndef(JIFFY_NO_MAPS).
  22. to_map_ejson({Props}) ->
  23. NewProps = [{K, to_map_ejson(V)} || {K, V} <- Props],
  24. maps:from_list(NewProps);
  25. to_map_ejson(Vals) when is_list(Vals) ->
  26. [to_map_ejson(V) || V <- Vals];
  27. to_map_ejson(Val) ->
  28. Val.
  29. prop_map_encode_decode() ->
  30. ?FORALL(Data, json(),
  31. begin
  32. MapData = to_map_ejson(Data),
  33. MapData == jiffy:decode(jiffy:encode(MapData), [return_maps])
  34. end
  35. ).
  36. -endif.
  37. prop_encode_decode_pretty() ->
  38. ?FORALL(Data, json(),
  39. begin
  40. Data == jiffy:decode(jiffy:encode(Data, [pretty]))
  41. end
  42. ).
  43. prop_encode_not_crash() ->
  44. ?FORALL(Data, any(), begin catch jiffy:encode(Data), true end).
  45. prop_decode_not_crash_bin() ->
  46. ?FORALL(Data, binary(), begin catch jiffy:decode(Data), true end).
  47. prop_decode_not_crash_any() ->
  48. ?FORALL(Data, any(), begin catch jiffy:decode(Data), true end).
  49. % JSON Generation
  50. json_null() ->
  51. null.
  52. json_boolean() ->
  53. oneof([true, false]).
  54. json_number() ->
  55. oneof([integer(), float()]).
  56. json_string() ->
  57. escaped_utf8_bin().
  58. json_list(S) when S =< 0 ->
  59. [];
  60. json_list(S) ->
  61. ?LETSHRINK(
  62. [ListSize],
  63. [integer(0, S)],
  64. vector(ListSize, json_text(S - ListSize))
  65. ).
  66. json_object(S) when S =< 0 ->
  67. {[]};
  68. json_object(S) ->
  69. ?LETSHRINK(
  70. [ObjectSize],
  71. [integer(0, S)],
  72. {vector(ObjectSize, {json_string(), json_text(S - ObjectSize)})}
  73. ).
  74. json_value() ->
  75. oneof([
  76. json_null(),
  77. json_boolean(),
  78. json_string(),
  79. json_number()
  80. ]).
  81. json_text(S) when S > 0 ->
  82. ?LAZY(oneof([
  83. json_list(S),
  84. json_object(S)
  85. ]));
  86. json_text(_) ->
  87. json_value().
  88. json() ->
  89. ?SIZED(S, json_text(S)).
  90. %% XXX: Add generators
  91. %
  92. % We should add generators that generate JSON binaries directly
  93. % so we can test things that aren't produced by the encoder.
  94. %
  95. % We should also have a version of the JSON generator that inserts
  96. % errors into the JSON that we can test for.
  97. escaped_utf8_bin() ->
  98. ?SUCHTHAT(Bin,
  99. ?LET(S, ?SUCHTHAT(L, list(escaped_char()), L /= []),
  100. unicode:characters_to_binary(S, unicode, utf8)),
  101. is_binary(Bin)
  102. ).
  103. escaped_char() ->
  104. ?LET(C, char(),
  105. case C of
  106. $" -> "\\\"";
  107. C when C == 65534 -> 65533;
  108. C when C == 65535 -> 65533;
  109. C when C > 1114111 -> 1114111;
  110. C -> C
  111. end
  112. ).
  113. -endif.