Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

156 строки
3.1 KiB

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