- % This file is part of Jiffy released under the MIT license.
- % See the LICENSE file for more information.
-
- -module(jiffy_11_proper_tests).
-
- -ifdef(JIFFY_DEV).
-
- -include_lib("proper/include/proper.hrl").
- -include_lib("eunit/include/eunit.hrl").
- -include("jiffy_util.hrl").
-
- opts() ->
- [
- {max_size, 15},
- {numtests, 1000}
- ].
-
- run(Name) ->
- {msg("~s", [Name]), [
- {timeout, 300, ?_assert(proper:quickcheck(?MODULE:Name(), opts()))}
- ]}.
-
- proper_encode_decode_test_() ->
- [
- run(prop_enc_dec),
- run(prop_enc_dec_pretty),
- run(prop_enc_no_crash),
- run(prop_dec_no_crash_bin),
- run(prop_dec_no_crash_any)
- ].
-
- prop_enc_dec() ->
- ?FORALL(Data, json(),
- begin
- %io:format(standard_error, "Data: ~p~n", [Data]),
- Data == jiffy:decode(jiffy:encode(Data))
- end
- ).
-
- -ifndef(JIFFY_NO_MAPS).
- to_map_ejson({Props}) ->
- NewProps = [{K, to_map_ejson(V)} || {K, V} <- Props],
- maps:from_list(NewProps);
- to_map_ejson(Vals) when is_list(Vals) ->
- [to_map_ejson(V) || V <- Vals];
- to_map_ejson(Val) ->
- Val.
-
- prop_map_enc_dec() ->
- ?FORALL(Data, json(),
- begin
- MapData = to_map_ejson(Data),
- MapData == jiffy:decode(jiffy:encode(MapData), [return_maps])
- end
- ).
- -endif.
-
- prop_enc_dec_pretty() ->
- ?FORALL(Data, json(),
- begin
- Data == jiffy:decode(jiffy:encode(Data, [pretty]))
- end
- ).
-
- prop_enc_no_crash() ->
- ?FORALL(Data, any(), begin catch jiffy:encode(Data), true end).
-
- prop_dec_no_crash_bin() ->
- ?FORALL(Data, binary(), begin catch jiffy:decode(Data), true end).
-
- prop_dec_no_crash_any() ->
- ?FORALL(Data, any(), begin catch jiffy:decode(Data), true end).
-
-
- % JSON Generation
-
-
- json_null() ->
- null.
-
-
- json_boolean() ->
- oneof([true, false]).
-
-
- json_number() ->
- oneof([integer(), float()]).
-
-
- json_string() ->
- escaped_utf8_bin().
-
-
- json_list(S) when S =< 0 ->
- [];
- json_list(S) ->
- ?LETSHRINK(
- [ListSize],
- [integer(0, S)],
- vector(ListSize, json_text(S - ListSize))
- ).
-
-
- json_object(S) when S =< 0 ->
- {[]};
- json_object(S) ->
- ?LETSHRINK(
- [ObjectSize],
- [integer(0, S)],
- {vector(ObjectSize, {json_string(), json_text(S - ObjectSize)})}
- ).
-
-
- json_value() ->
- oneof([
- json_null(),
- json_boolean(),
- json_string(),
- json_number()
- ]).
-
-
- json_text(S) when S > 0 ->
- ?LAZY(oneof([
- json_list(S),
- json_object(S)
- ]));
- json_text(_) ->
- json_value().
-
-
- json() ->
- ?SIZED(S, json_text(S)).
-
-
- %% XXX: Add generators
- %
- % We should add generators that generate JSON binaries directly
- % so we can test things that aren't produced by the encoder.
- %
- % We should also have a version of the JSON generator that inserts
- % errors into the JSON that we can test for.
-
-
- escaped_utf8_bin() ->
- ?SUCHTHAT(Bin,
- ?LET(S, ?SUCHTHAT(L, list(escaped_char()), L /= []),
- unicode:characters_to_binary(S, unicode, utf8)),
- is_binary(Bin)
- ).
-
-
- escaped_char() ->
- ?LET(C, char(),
- case C of
- $" -> "\\\"";
- C when C == 65534 -> 65533;
- C when C == 65535 -> 65533;
- C when C > 1114111 -> 1114111;
- C -> C
- end
- ).
-
- -endif.
|