Procházet zdrojové kódy

Implement PropEr tests for JSON parsing

Big thanks to Dmitry Groshev [1] for help getting PropEr tests into
Jiffy. These generate valid EJSON to check parsing as well as check
that random inputs don't cause segfaults or other nasty effects.

Future improvements would be to write a JSON generator as well as a
version that introduces known errors into the binary for checking known
parsing errors as well.

[1] https://github.com/si14

Fixes: #10
pull/11/head
Paul J. Davis před 13 roky
rodič
revize
ffa2fafa28
4 změnil soubory, kde provedl 178 přidání a 5 odebrání
  1. +3
    -1
      .gitignore
  2. +23
    -4
      Makefile
  3. +14
    -0
      rebar.config
  4. +138
    -0
      test/jiffy_tests.erl

+ 3
- 1
.gitignore Zobrazit soubor

@ -1,4 +1,6 @@
*.app
*.beam
*.o
*.so
ebin/jiffy.app
.eunit
deps

+ 23
- 4
Makefile Zobrazit soubor

@ -1,11 +1,30 @@
all: build
%.beam: %.erl
erlc -o test/ $<
clean:
./rebar clean
rm -rf logs
rm -rf .eunit
deps: ./deps/
./rebar get-deps update-deps
build: c_src/decoder.c
build: deps
./rebar compile
check: test/etap.beam test/util.beam
etap: test/etap.beam test/util.beam
prove test/*.t
eunit:
./rebar eunit skip_deps=true
check: etap eunit
%.beam: %.erl
erlc -o test/ $<

+ 14
- 0
rebar.config Zobrazit soubor

@ -1,3 +1,8 @@
{deps, [
{proper, ".*", {git, "https://github.com/manopapad/proper.git", "master"}}
]}.
{port_sources, ["c_src/*.c"]}.
{so_name, "jiffy.so"}.
{port_envs, [
@ -15,3 +20,12 @@
{"darwin10.*-32$", "CXXFLAGS", "-m32"},
{"darwin10.*-32$", "LDFLAGS", "-arch i386"}
]}.
{eunit_opts, [
verbose,
{report, {
eunit_surefire, [{dir,"."}]
}}
]}.

+ 138
- 0
test/jiffy_tests.erl Zobrazit soubor

@ -0,0 +1,138 @@
% This file is part of Jiffy released under the MIT license.
% See the LICENSE file for more information.
-module(jiffy_tests).
-include_lib("proper/include/proper.hrl").
-include_lib("eunit/include/eunit.hrl").
proper_test_() ->
PropErOpts = [
{to_file, user},
{max_size, 60},
{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]),
ExpData = conv_keys(Data),
ExpData == jiffy:decode(jiffy:encode(Data))
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_key() ->
oneof([json_string(), escaped_atom()]).
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_key(), 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)).
escaped_atom() ->
?LET(A, atom(),
unicode:characters_to_binary(atom_to_list(A), unicode, utf8)
).
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 -> C
end
).
% Atoms get munged to binaries in the round trip.
conv_keys({Props}) ->
{lists:map(fun({K, V}) -> {conv_key(K), conv_keys(V)} end, Props)};
conv_keys(Vals) when is_list(Vals) ->
lists:map(fun(V) -> conv_keys(V) end, Vals);
conv_keys(Other) ->
Other.
conv_key(K) when is_atom(K) ->
list_to_binary(atom_to_list(K));
conv_key(K) ->
K.

Načítá se…
Zrušit
Uložit