diff --git a/quickcheck/aefate_eqc.erl b/quickcheck/aefate_eqc.erl index e9368fd..25823a0 100644 --- a/quickcheck/aefate_eqc.erl +++ b/quickcheck/aefate_eqc.erl @@ -24,7 +24,7 @@ prop_roundtrip() -> end)). prop_format_scan() -> - ?FORALL(FateData, fate_data(), + ?FORALL(FateData, fate_data([variant, map]), ?WHENFAIL(eqc:format("Trying to format ~p failed~n", [FateData]), begin String = aeb_fate_data:format(FateData), @@ -72,13 +72,14 @@ prop_fuzz() -> prop_order() -> - ?FORALL(Items, vector(3, fate_data()), + ?FORALL(Items, vector(3, fate_data([variant, map])), begin %% Use lt to take minimum Min = lt_min(Items), Max = lt_max(Items), conjunction([ {minimum, is_empty([ {Min, '>', I} || I<-Items, aeb_fate_data:lt(I, Min)])}, - {maximum, is_empty([ {Max, '<', I} || I<-Items, aeb_fate_data:lt(Max, I)])}]) + {maximum, is_empty([ {Max, '<', I} || I<-Items, aeb_fate_data:lt(Max, I)])}, + {asym, aeb_fate_data:lt(Min, Max) orelse Min == Max}]) end). lt_min([X, Y | Rest]) -> @@ -101,18 +102,24 @@ prop_idempotent() -> aeb_fate_encoding:sort(aeb_fate_encoding:sort(Items)))). + +fate_data(Kind) -> + ?SIZED(Size, ?LET(Data, fate_data(Size, Kind), eqc_symbolic:eval(Data))). + fate_data() -> - ?SIZED(Size, ?LET(Data, fate_data(Size, [map, variant]), eqc_symbolic:eval(Data))). + fate_data([map, variant, store_map]). +%% keys may contain variants but no maps fate_data_key() -> - ?SIZED(Size, ?LET(Data, fate_data(Size div 4, [variant]), eqc_symbolic:eval(Data))). + fate_data([variant]). -fate_data(0, _Options) -> +fate_data(0, Options) -> ?LAZY( frequency( - [{5, oneof([fate_integer(), fate_boolean(), fate_nil(), fate_unit()])}, - {1, oneof([fate_string(), fate_address(), fate_bytes(), fate_contract(), - fate_oracle(), fate_oracle_q(), fate_bits(), fate_channel()])}])); + [{50, oneof([fate_integer(), fate_boolean(), fate_nil(), fate_unit()])}, + {10, oneof([fate_string(), fate_address(), fate_bytes(), fate_contract(), + fate_oracle(), fate_oracle_q(), fate_bits(), fate_channel()])}] ++ + [{1, fate_store_map()} || lists:member(store_map, Options)])); fate_data(Size, Options) -> ?LAZY( oneof([fate_data(0, Options), @@ -161,9 +168,20 @@ fate_list(Size, Options) -> fate_map(Size, Options) -> ?LET(N, choose(0, 6), ?LETSHRINK(Values, fate_values(Size, N, Options), - ?LET(Keys, vector(length(Values), fate_data(Size div max(1, N * 2), Options -- [map])), + ?LET(Keys, vector(length(Values), fate_data(Size div max(1, N * 2), Options -- [map, store_map])), return(aeb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))). +fate_store_map() -> + %% only #{} is allowed as cache in serialization + ?LET(X, oneof([int(), largeint()]), + return(aeb_fate_data:make_store_map(abs(X)))). + +fate_bad_map() -> + ?LET(N, choose(0, 6), + ?LET(Values, vector(N, ?SIZED(Size, resize(Size div 8, fate_data()))), + ?LET(Keys, vector(N, ?SIZED(Size, resize(Size div 4, fate_data()))), + return(aeb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))). + non_quote_string() -> ?SUCHTHAT(S, utf8(), [ quote || <<34>> <= S ] == []).