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.

135 line
2.6 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. prop_encode_decode_pretty() ->
  22. ?FORALL(Data, json(),
  23. begin
  24. Data == jiffy:decode(jiffy:encode(Data, [pretty]))
  25. end
  26. ).
  27. prop_encode_not_crash() ->
  28. ?FORALL(Data, any(), begin catch jiffy:encode(Data), true end).
  29. prop_decode_not_crash_bin() ->
  30. ?FORALL(Data, binary(), begin catch jiffy:decode(Data), true end).
  31. prop_decode_not_crash_any() ->
  32. ?FORALL(Data, any(), begin catch jiffy:decode(Data), true end).
  33. % JSON Generation
  34. json_null() ->
  35. null.
  36. json_boolean() ->
  37. oneof([true, false]).
  38. json_number() ->
  39. oneof([integer(), float()]).
  40. json_string() ->
  41. escaped_utf8_bin().
  42. json_list(S) when S =< 0 ->
  43. [];
  44. json_list(S) ->
  45. ?LETSHRINK(
  46. [ListSize],
  47. [integer(0, S)],
  48. vector(ListSize, json_text(S - ListSize))
  49. ).
  50. json_object(S) when S =< 0 ->
  51. {[]};
  52. json_object(S) ->
  53. ?LETSHRINK(
  54. [ObjectSize],
  55. [integer(0, S)],
  56. {vector(ObjectSize, {json_string(), json_text(S - ObjectSize)})}
  57. ).
  58. json_value() ->
  59. oneof([
  60. json_null(),
  61. json_boolean(),
  62. json_string(),
  63. json_number()
  64. ]).
  65. json_text(S) when S > 0 ->
  66. ?LAZY(oneof([
  67. json_list(S),
  68. json_object(S)
  69. ]));
  70. json_text(_) ->
  71. json_value().
  72. json() ->
  73. ?SIZED(S, json_text(S)).
  74. %% XXX: Add generators
  75. %
  76. % We should add generators that generate JSON binaries directly
  77. % so we can test things that aren't produced by the encoder.
  78. %
  79. % We should also have a version of the JSON generator that inserts
  80. % errors into the JSON that we can test for.
  81. escaped_utf8_bin() ->
  82. ?SUCHTHAT(Bin,
  83. ?LET(S, ?SUCHTHAT(L, list(escaped_char()), L /= []),
  84. unicode:characters_to_binary(S, unicode, utf8)),
  85. is_binary(Bin)
  86. ).
  87. escaped_char() ->
  88. ?LET(C, char(),
  89. case C of
  90. $" -> "\\\"";
  91. C when C == 65534 -> 65533;
  92. C when C == 65535 -> 65533;
  93. C when C > 1114111 -> 1114111;
  94. C -> C
  95. end
  96. ).
  97. -endif.