Merge pull request #26 from aeternity/PT-165180296-fix-fate-scanner
Pt 165180296 fix fate scanner
This commit is contained in:
commit
afcc6fd31a
2
.gitignore
vendored
2
.gitignore
vendored
@ -20,3 +20,5 @@ src/aeb_fate_pp.erl
|
|||||||
*.erl~
|
*.erl~
|
||||||
*.hrl~
|
*.hrl~
|
||||||
*.aes~
|
*.aes~
|
||||||
|
doc
|
||||||
|
cover
|
||||||
|
107
quickcheck/aefate_eqc.erl
Normal file
107
quickcheck/aefate_eqc.erl
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
%%% @author Thomas Arts
|
||||||
|
%%% @copyright (C) 2018, Thomas Arts
|
||||||
|
%%% @doc Use `rebar3 as eqc shell` to run properties in the shell
|
||||||
|
%%%
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
|
||||||
|
|
||||||
|
-module(aefate_eqc).
|
||||||
|
|
||||||
|
-include_lib("eqc/include/eqc.hrl").
|
||||||
|
|
||||||
|
-compile([export_all, nowarn_export_all]).
|
||||||
|
|
||||||
|
prop_roundtrip() ->
|
||||||
|
?FORALL(FateData, fate_type(),
|
||||||
|
measure(bytes, size(term_to_binary(FateData)),
|
||||||
|
begin
|
||||||
|
Serialized = aeb_fate_encoding:serialize(FateData),
|
||||||
|
?WHENFAIL(eqc:format("Serialized ~p to ~p~n", [FateData, Serialized]),
|
||||||
|
equals(aeb_fate_encoding:deserialize(Serialized), FateData))
|
||||||
|
end
|
||||||
|
)).
|
||||||
|
|
||||||
|
prop_format() ->
|
||||||
|
?FORALL(FateData, fate_type(),
|
||||||
|
?WHENFAIL(eqc:format("Trying to format ~p failed~n",[FateData]),
|
||||||
|
begin
|
||||||
|
String = aeb_fate_data:format(FateData),
|
||||||
|
collect([FateData, unicode:characters_to_binary(String, latin1)], true)
|
||||||
|
end)).
|
||||||
|
|
||||||
|
prop_format_scan() ->
|
||||||
|
?FORALL(FateData, fate_type(),
|
||||||
|
?WHENFAIL(eqc:format("Trying to format ~p failed~n~p~n", [FateData, catch unicode:characters_to_list(aeb_fate_data:format(FateData), utf8) ]),
|
||||||
|
begin
|
||||||
|
String = aeb_fate_data:format(FateData),
|
||||||
|
{ok, _Scanned, _} = aeb_fate_asm_scan:scan(unicode:characters_to_list(String)),
|
||||||
|
true
|
||||||
|
end)).
|
||||||
|
|
||||||
|
fate_type() ->
|
||||||
|
?SIZED(Size, fate_type(Size, [map])).
|
||||||
|
|
||||||
|
fate_type(0, _Options) ->
|
||||||
|
?LAZY(
|
||||||
|
oneof([fate_integer(),
|
||||||
|
fate_boolean(),
|
||||||
|
fate_nil(),
|
||||||
|
fate_unit(),
|
||||||
|
fate_string(),
|
||||||
|
fate_address(),
|
||||||
|
fate_hash(),
|
||||||
|
fate_signature(),
|
||||||
|
fate_contract(),
|
||||||
|
fate_oracle(),
|
||||||
|
fate_name(),
|
||||||
|
fate_bits(),
|
||||||
|
fate_channel()]));
|
||||||
|
fate_type(Size, Options) ->
|
||||||
|
?LETSHRINK([Smaller], [?LAZY(fate_type(Size div 5, Options))],
|
||||||
|
oneof([?LAZY(fate_type(Size - 1, Options)),
|
||||||
|
?LAZY(fate_list( Smaller )),
|
||||||
|
?LAZY(fate_tuple( list( Smaller ))),
|
||||||
|
?LAZY(fate_variant(?LET(L, list( Smaller), list_to_tuple(L))))] ++
|
||||||
|
[
|
||||||
|
?LAZY(fate_map( fate_type(Size div 3, Options -- [map]),
|
||||||
|
Smaller))
|
||||||
|
|| lists:member(map, Options)
|
||||||
|
])).
|
||||||
|
|
||||||
|
|
||||||
|
fate_integer() -> oneof([int(), largeint()]).
|
||||||
|
fate_bits() -> {bits, oneof([int(), largeint()])}.
|
||||||
|
fate_boolean() -> elements([true, false]).
|
||||||
|
fate_nil() -> [].
|
||||||
|
fate_unit() -> {tuple, {}}.
|
||||||
|
fate_string() -> ?SUCHTHAT(S, utf8(), string:find(S, "\"") == nomatch).
|
||||||
|
fate_address() -> {address, non_zero_binary(256 div 8)}.
|
||||||
|
fate_hash() -> {hash, non_zero_binary(32)}.
|
||||||
|
fate_signature() -> {signature, non_zero_binary(64)}.
|
||||||
|
fate_contract() -> {contract, non_zero_binary(256 div 8)}.
|
||||||
|
fate_oracle() -> {oracle, non_zero_binary(256 div 8)}.
|
||||||
|
fate_name() -> {name, non_zero_binary(256 div 8)}.
|
||||||
|
fate_channel() -> {channel, non_zero_binary(256 div 8)}.
|
||||||
|
|
||||||
|
%% May shrink to fate_unit
|
||||||
|
fate_tuple(ListGen) ->
|
||||||
|
{tuple, ?LET(Elements, ListGen, list_to_tuple(Elements))}.
|
||||||
|
|
||||||
|
fate_variant(TupleGen) ->
|
||||||
|
?LET({L1, L2, Tuple}, {list(choose(0, 255)), list(choose(0,255)), TupleGen},
|
||||||
|
{variant, L1 ++ [size(Tuple)] ++ L2, length(L1), Tuple}).
|
||||||
|
|
||||||
|
fate_list(Gen) ->
|
||||||
|
oneof([fate_nil(), ?SHRINK(list(Gen), [fate_nil()])]).
|
||||||
|
|
||||||
|
fate_map(KeyGen, ValGen) ->
|
||||||
|
map(KeyGen, ValGen).
|
||||||
|
|
||||||
|
|
||||||
|
non_zero_binary(N) ->
|
||||||
|
Bits = N*8,
|
||||||
|
?SUCHTHAT(Bin, binary(N), begin <<V:Bits>> = Bin, V =/= 0 end).
|
||||||
|
|
||||||
|
char() ->
|
||||||
|
choose(1, 255).
|
@ -13,12 +13,12 @@ HEXDIGIT = [0-9a-fA-F]
|
|||||||
LOWER = [a-z_]
|
LOWER = [a-z_]
|
||||||
UPPER = [A-Z]
|
UPPER = [A-Z]
|
||||||
BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]
|
BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]
|
||||||
BASE64 = [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=]
|
BASE64 = [A-Za-z0-9+/=]
|
||||||
INT = {DIGIT}+
|
INT = {DIGIT}+
|
||||||
HEX = 0x{HEXDIGIT}+
|
HEX = 0x{HEXDIGIT}+
|
||||||
OBJECT = @[a-z][a-z]_{BASE58}+
|
OBJECT = @[a-z][a-z]_{BASE58}+
|
||||||
HASH = #{BASE64}+
|
HASH = #{BASE64}+
|
||||||
SIG = \$\sg_{BASE58}+
|
SIG = \$sg_{BASE58}+
|
||||||
WS = [\000-\s]
|
WS = [\000-\s]
|
||||||
ID = {LOWER}[a-zA-Z0-9_]*
|
ID = {LOWER}[a-zA-Z0-9_]*
|
||||||
STRING = "[^"]*"
|
STRING = "[^"]*"
|
||||||
@ -51,8 +51,11 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
|||||||
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
||||||
-{INT} :
|
-{INT} :
|
||||||
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
{token, {int, TokenLine, parse_int(TokenChars)}}.
|
||||||
|
|
||||||
|
%% Due to the definition of STRING the tokens start and end with a quote ".
|
||||||
{STRING} :
|
{STRING} :
|
||||||
{token, {string, TokenLine, list_to_binary(TokenChars)}}.
|
{token, {string, TokenLine, unicode:characters_to_binary(
|
||||||
|
lists:sublist(TokenChars, 2, length(TokenChars) - 2))}}.
|
||||||
{BITS} :
|
{BITS} :
|
||||||
{token, {bits, TokenLine, bits(TokenChars)}}.
|
{token, {bits, TokenLine, bits(TokenChars)}}.
|
||||||
|
|
||||||
@ -112,7 +115,7 @@ parse_hash("#" ++ Chars) ->
|
|||||||
base64:decode(Chars).
|
base64:decode(Chars).
|
||||||
|
|
||||||
parse_object([_|Chars]) ->
|
parse_object([_|Chars]) ->
|
||||||
case aeser_api_encoder:decode(list_to_binary(Chars)) of
|
case aeser_api_encoder:decode(unicode:characters_to_binary(Chars)) of
|
||||||
{account_pubkey, Bin} -> {address, Bin};
|
{account_pubkey, Bin} -> {address, Bin};
|
||||||
{contract_pubkey, Bin} -> {contract, Bin};
|
{contract_pubkey, Bin} -> {contract, Bin};
|
||||||
{oracle_pubkey, Bin} -> {oracle, Bin};
|
{oracle_pubkey, Bin} -> {oracle, Bin};
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
-type fate_signature() :: ?FATE_SIGNATURE_T.
|
-type fate_signature() :: ?FATE_SIGNATURE_T.
|
||||||
-type fate_variant() :: ?FATE_VARIANT_T.
|
-type fate_variant() :: ?FATE_VARIANT_T.
|
||||||
-type fate_tuple() :: ?FATE_TUPLE_T.
|
-type fate_tuple() :: ?FATE_TUPLE_T.
|
||||||
|
-type fate_bits() :: ?FATE_BITS_T.
|
||||||
|
|
||||||
-type fate_type_type() :: integer
|
-type fate_type_type() :: integer
|
||||||
| boolean
|
| boolean
|
||||||
@ -34,7 +35,7 @@
|
|||||||
| name
|
| name
|
||||||
| channel
|
| channel
|
||||||
| bits
|
| bits
|
||||||
| {variant, list(), integer()}.
|
| {variant, list()}.
|
||||||
|
|
||||||
|
|
||||||
-type fate_type() ::
|
-type fate_type() ::
|
||||||
@ -54,7 +55,7 @@
|
|||||||
| fate_channel()
|
| fate_channel()
|
||||||
| fate_variant()
|
| fate_variant()
|
||||||
| fate_map()
|
| fate_map()
|
||||||
| fate_type_type().
|
| fate_bits().
|
||||||
|
|
||||||
-export_type([fate_type/0
|
-export_type([fate_type/0
|
||||||
, fate_boolean/0
|
, fate_boolean/0
|
||||||
@ -73,6 +74,7 @@
|
|||||||
, fate_channel/0
|
, fate_channel/0
|
||||||
, fate_variant/0
|
, fate_variant/0
|
||||||
, fate_map/0
|
, fate_map/0
|
||||||
|
, fate_bits/0
|
||||||
, fate_type_type/0
|
, fate_type_type/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
@ -120,6 +122,9 @@ make_string(S) when is_list(S) ->
|
|||||||
?FATE_STRING(list_to_binary(lists:flatten(S)));
|
?FATE_STRING(list_to_binary(lists:flatten(S)));
|
||||||
make_string(S) when is_binary(S) -> ?FATE_STRING(S).
|
make_string(S) when is_binary(S) -> ?FATE_STRING(S).
|
||||||
|
|
||||||
|
%% Tag points to the selected variant (zero based)
|
||||||
|
%% The arity of this variant is read from the list of provided arities
|
||||||
|
%% and should match the size of the given tuple.
|
||||||
make_variant(Arities, Tag, Values) ->
|
make_variant(Arities, Tag, Values) ->
|
||||||
Arities = [A || A <- Arities, is_integer(A), A < 256],
|
Arities = [A || A <- Arities, is_integer(A), A < 256],
|
||||||
Size = length(Arities),
|
Size = length(Arities),
|
||||||
@ -205,7 +210,7 @@ format(L) when ?IS_FATE_LIST(L) -> format_list(?FATE_LIST_VALUE(L));
|
|||||||
format(?FATE_UNIT) -> "()";
|
format(?FATE_UNIT) -> "()";
|
||||||
format(?FATE_TUPLE(T)) ->
|
format(?FATE_TUPLE(T)) ->
|
||||||
["( ", lists:join(", ", [ format(E) || E <- erlang:tuple_to_list(T)]), " )"];
|
["( ", lists:join(", ", [ format(E) || E <- erlang:tuple_to_list(T)]), " )"];
|
||||||
format(S) when ?IS_FATE_STRING(S) -> [S];
|
format(S) when ?IS_FATE_STRING(S) -> ["\"", S, "\""];
|
||||||
format(?FATE_BITS(B)) when B >= 0 ->
|
format(?FATE_BITS(B)) when B >= 0 ->
|
||||||
["<", format_bits(B, "") , ">"];
|
["<", format_bits(B, "") , ">"];
|
||||||
format(?FATE_BITS(B)) when B < 0 ->
|
format(?FATE_BITS(B)) when B < 0 ->
|
||||||
@ -213,7 +218,7 @@ format(?FATE_BITS(B)) when B < 0 ->
|
|||||||
format(?FATE_VARIANT(Arities, Tag, T)) ->
|
format(?FATE_VARIANT(Arities, Tag, T)) ->
|
||||||
["(| ",
|
["(| ",
|
||||||
lists:join("| ",
|
lists:join("| ",
|
||||||
[io_lib:format("~p", [Arities]),
|
[format_arities(Arities),
|
||||||
integer_to_list(Tag) |
|
integer_to_list(Tag) |
|
||||||
[format(make_tuple(T))]]),
|
[format(make_tuple(T))]]),
|
||||||
" |)"];
|
" |)"];
|
||||||
@ -244,6 +249,9 @@ format_nbits(N, Acc) ->
|
|||||||
Bit = $1 - (N band 1),
|
Bit = $1 - (N band 1),
|
||||||
format_nbits(N bsr 1, [Bit|Acc]).
|
format_nbits(N bsr 1, [Bit|Acc]).
|
||||||
|
|
||||||
|
format_arities(Arities) ->
|
||||||
|
["[ ", lists:join(", ", [integer_to_list(E) || E <- Arities]), " ]"].
|
||||||
|
|
||||||
format_list(List) ->
|
format_list(List) ->
|
||||||
["[ ", lists:join(", ", [format(E) || E <- List]), " ]"].
|
["[ ", lists:join(", ", [format(E) || E <- List]), " ]"].
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{application, aebytecode,
|
{application, aebytecode,
|
||||||
[{description, "Bytecode definitions, serialization and deserialization for aeternity."},
|
[{description, "Bytecode definitions, serialization and deserialization for aeternity."},
|
||||||
{vsn, "2.0.1"},
|
{vsn, "2.1.0"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications,
|
{applications,
|
||||||
[kernel,
|
[kernel,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user