Map 'hash' as known api type, add some more tests (#56)
All checks were successful
Gajumaru Serialization Tests / tests (push) Successful in -2m53s

I noticed that the 'hash' serialization type wasn't in the `known_type()` set, although it was supported otherwise.
This PR adds it to the `known_type()` and also exports the type `gmser_api_encoder:known_type()`.

Also, some more tests are added to try to detect this sort of thing in the future.

Co-authored-by: Ulf Wiger <ulf@wiger.net>
Reviewed-on: #56
This commit is contained in:
Ulf Wiger 2026-03-24 21:23:20 +09:00
parent 2b24b17af3
commit 05bbf058be
2 changed files with 65 additions and 7 deletions

View File

@ -13,7 +13,8 @@
safe_decode/2, safe_decode/2,
byte_size_for_type/1]). byte_size_for_type/1]).
-export_type([encoded/0]). -export_type([encoded/0,
known_type/0]).
-type known_type() :: key_block_hash -type known_type() :: key_block_hash
| micro_block_hash | micro_block_hash
@ -38,6 +39,7 @@
| native_token | native_token
| commitment | commitment
| peer_pubkey | peer_pubkey
| hash
| state | state
| poi | poi
| state_trees | state_trees

View File

@ -22,10 +22,39 @@
, {native_token , 32} , {native_token , 32}
, {commitment , 32} , {commitment , 32}
, {peer_pubkey , 32} , {peer_pubkey , 32}
, {hash , 32}
, {state , 32} , {state , 32}
, {poi , not_applicable}]). , {poi , not_applicable}]).
encode_decode_test_() -> encode_decode_test_() ->
encode_decode_test_(?TYPES).
encode_decode_known_types_test_() ->
KnownTypes = known_types(),
SizedTypes = [{T, ?TEST_MODULE:byte_size_for_type(T)} || T <- KnownTypes],
encode_decode_test_(SizedTypes).
prefixes_are_known_types_test() ->
MappedPfxs = mapped_prefixes(),
KnownTypes = known_types(),
lists:foreach(
fun({Pfx, Type}) ->
case lists:member(Type, KnownTypes) of
true -> ok;
false ->
error({not_a_known_type, Pfx, Type})
end
end, MappedPfxs),
lists:foreach(
fun(Type) ->
case lists:keyfind(Type, 2, MappedPfxs) of
{_, _} -> ok;
false ->
error({has_no_mapped_prefix, Type})
end
end, KnownTypes).
encode_decode_test_(Types) ->
[{"Byte sizes are correct", [{"Byte sizes are correct",
fun() -> fun() ->
lists:foreach( lists:foreach(
@ -33,7 +62,7 @@ encode_decode_test_() ->
{_Type, _, ByteSize} = {Type, ByteSize, {_Type, _, ByteSize} = {Type, ByteSize,
?TEST_MODULE:byte_size_for_type(Type)} ?TEST_MODULE:byte_size_for_type(Type)}
end, end,
?TYPES) Types)
end end
}, },
{"Serialize/deserialize known types", {"Serialize/deserialize known types",
@ -50,7 +79,7 @@ encode_decode_test_() ->
{Type, Key} = ?TEST_MODULE:decode(EncodedKey), {Type, Key} = ?TEST_MODULE:decode(EncodedKey),
{ok, Key} = ?TEST_MODULE:safe_decode(Type, EncodedKey) {ok, Key} = ?TEST_MODULE:safe_decode(Type, EncodedKey)
end, end,
?TYPES) Types)
end end
}, },
{"Key size check works", {"Key size check works",
@ -68,7 +97,7 @@ encode_decode_test_() ->
CheckIlligalSize(ByteSize - 1), CheckIlligalSize(ByteSize - 1),
CheckIlligalSize(ByteSize + 1) CheckIlligalSize(ByteSize + 1)
end, end,
?TYPES) Types)
end end
}, },
{"Missing prefix", {"Missing prefix",
@ -91,7 +120,7 @@ encode_decode_test_() ->
<<_WholePrefix:3/unit:8, RestOfKey2/binary>> = EncodedKey, <<_WholePrefix:3/unit:8, RestOfKey2/binary>> = EncodedKey,
{error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, RestOfKey2) {error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, RestOfKey2)
end, end,
?TYPES) Types)
end end
}, },
{"Piece of encoded key", {"Piece of encoded key",
@ -110,7 +139,7 @@ encode_decode_test_() ->
{error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, HalfKey), {error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, HalfKey),
{error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, RestOfKey) {error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, RestOfKey)
end, end,
?TYPES) Types)
end end
}, },
{"Encode/decode binary with only zeros", {"Encode/decode binary with only zeros",
@ -131,8 +160,35 @@ encode_decode_test_() ->
Encoded1 = base58:binary_to_base58(Bin), Encoded1 = base58:binary_to_base58(Bin),
Decoded1 = base58:base58_to_binary(Encoded1), Decoded1 = base58:base58_to_binary(Encoded1),
?assertEqual(Bin, Decoded1) ?assertEqual(Bin, Decoded1)
end, ?TYPES) end, Types)
end, end,
Bins) Bins)
end} end}
]. ].
known_types() ->
Forms = get_forms(),
[{type, _, union, Types}] =
[Def || {attribute, _, type, {known_type, Def, []}} <- Forms],
[Name || {atom,_, Name} <- Types].
mapped_prefixes() ->
Forms = get_forms(),
[Clauses] = [Cs || {function,_,pfx2type,1,Cs} <- Forms],
Abst = [{B, A} || {clause,_,[B],[],[A]} <- Clauses],
lists:map(
fun({B, A}) ->
{eval_expr(B), eval_expr(A)}
end, Abst).
get_forms() ->
get_forms(code:which(?TEST_MODULE)).
get_forms(Beam) ->
{ok, {_, [{abstract_code, {raw_abstract_v1, Forms}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
Forms.
eval_expr(Expr) ->
{value, Val, []} = erl_eval:expr(Expr, []),
Val.