Repository: couchdb-jiffy Updated Branches: refs/heads/master dc451c9f5 -> ef77de4aa
http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_10_short_double_tests.erl ---------------------------------------------------------------------- diff --git a/test/jiffy_10_short_double_tests.erl b/test/jiffy_10_short_double_tests.erl new file mode 100644 index 0000000..1c1d069 --- /dev/null +++ b/test/jiffy_10_short_double_tests.erl @@ -0,0 +1,34 @@ +% This file is part of Jiffy released under the MIT license. +% See the LICENSE file for more information. + +-module(jiffy_10_short_double_tests). + + +-include_lib("proper/include/proper.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-include("jiffy_util.hrl"). + + +filename() -> "../test/cases/short-doubles.txt". + + +short_double_test() -> + {ok, Fd} = file:open(filename(), [read, binary, raw]), + {"all doubles round trip", ?assertEqual(0, run(Fd, 0))}. + + +run(Fd, Acc) -> + case file:read_line(Fd) of + {ok, Data} -> + V1 = re:replace(iolist_to_binary(Data), <<"\.\n">>, <<"">>), + V2 = iolist_to_binary(V1), + V3 = <<34, V2/binary, 34>>, + R = jiffy:encode(jiffy:decode(V3)), + case R == V3 of + true -> run(Fd, Acc); + false -> run(Fd, Acc + 1) + end; + eof -> + Acc + end. + http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_11_proper_tests.erl ---------------------------------------------------------------------- diff --git a/test/jiffy_11_proper_tests.erl b/test/jiffy_11_proper_tests.erl new file mode 100644 index 0000000..aca542e --- /dev/null +++ b/test/jiffy_11_proper_tests.erl @@ -0,0 +1,164 @@ +% 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, 3600, ?_assert(proper:quickcheck(?MODULE:Name(), opts()))} + ]}. + +proper_encode_decode_test_() -> + {timeout, 3600, [ + 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. http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_tests.erl ---------------------------------------------------------------------- diff --git a/test/jiffy_tests.erl b/test/jiffy_tests.erl deleted file mode 100644 index 9ecea32..0000000 --- a/test/jiffy_tests.erl +++ /dev/null @@ -1,153 +0,0 @@ -% This file is part of Jiffy released under the MIT license. -% See the LICENSE file for more information. - --module(jiffy_tests). - --ifdef(JIFFY_DEV). - --include_lib("proper/include/proper.hrl"). --include_lib("eunit/include/eunit.hrl"). - - -proper_test_() -> - PropErOpts = [ - {to_file, user}, - {max_size, 15}, - {numtests, 1000} - ], - {timeout, 3600, ?_assertEqual([], proper:module(jiffy_tests, PropErOpts))}. - - -prop_encode_decode() -> - ?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_encode_decode() -> - ?FORALL(Data, json(), - begin - MapData = to_map_ejson(Data), - MapData == jiffy:decode(jiffy:encode(MapData), [return_maps]) - end - ). --endif. - -prop_encode_decode_pretty() -> - ?FORALL(Data, json(), - begin - Data == jiffy:decode(jiffy:encode(Data, [pretty])) - end - ). - -prop_encode_not_crash() -> - ?FORALL(Data, any(), begin catch jiffy:encode(Data), true end). - -prop_decode_not_crash_bin() -> - ?FORALL(Data, binary(), begin catch jiffy:decode(Data), true end). - -prop_decode_not_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. http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_util.hrl ---------------------------------------------------------------------- diff --git a/test/jiffy_util.hrl b/test/jiffy_util.hrl new file mode 100644 index 0000000..b8210e2 --- /dev/null +++ b/test/jiffy_util.hrl @@ -0,0 +1,25 @@ + +msg(Fmt, Args) -> + M1 = io_lib:format(Fmt, Args), + M2 = re:replace(M1, <<"\r">>, <<"\\\\r">>, [global]), + M3 = re:replace(M2, <<"\n">>, <<"\\\\n">>, [global]), + M4 = re:replace(M3, <<"\t">>, <<"\\\\t">>, [global]), + iolist_to_binary(M4). + + +hex(Bin) when is_binary(Bin) -> + H1 = [io_lib:format("16#~2.16.0B",[X]) || <<X:8>> <= Bin], + H2 = string:join(H1, ", "), + lists:flatten(io_lib:format("<<~s>>", [lists:flatten(H2)])). + + +dec(V) -> + jiffy:decode(V). + + +enc(V) -> + iolist_to_binary(jiffy:encode(V)). + + +enc(V, Opts) -> + iolist_to_binary(jiffy:encode(V, Opts)). http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/util.erl ---------------------------------------------------------------------- diff --git a/test/util.erl b/test/util.erl deleted file mode 100644 index ceaef89..0000000 --- a/test/util.erl +++ /dev/null @@ -1,44 +0,0 @@ --module(util). --export([test_good/1, test_good/2, test_errors/1]). - -test_good(Cases) -> - test_good(Cases, []). - -test_good(Cases, Options) -> - lists:foreach(fun(Case) -> check_good(Case, Options) end, Cases). - -test_errors(Cases) -> - lists:foreach(fun(Case) -> check_error(Case) end, Cases). - -ok_dec(J, _E) -> - lists:flatten(io_lib:format("Decoded ~p.", [J])). - -ok_enc(E, _J) -> - lists:flatten(io_lib:format("Encoded ~p", [E])). - -do_encode(E, Options) -> - iolist_to_binary(jiffy:encode(E, Options)). - -error_mesg(J) -> - lists:flatten(io_lib:format("Decoding ~p returns an error.", [J])). - -check_good({J, E}, Options) -> - etap:is(jiffy:decode(J), E, ok_dec(J, E)), - etap:is(do_encode(E, Options), J, ok_enc(E, J)); -check_good({J, E, J2}, Options) -> - etap:is(jiffy:decode(J), E, ok_dec(J, E)), - etap:is(do_encode(E, Options), J2, ok_enc(E, J2)). - -check_error({J, E}) -> - etap:fun_is( - fun({error, E1}) when E1 == E -> true; (E1) -> E1 end, - (catch jiffy:decode(J)), - error_mesg(J) - ); -check_error(J) -> - etap:fun_is( - fun({error, _}) -> true; (Else) -> Else end, - (catch jiffy:decode(J)), - error_mesg(J) - ). -
