From 04311f9c9958e9948a7f273df3e144db4db01e85 Mon Sep 17 00:00:00 2001 From: SpiveeWorks Date: Fri, 24 Jan 2025 18:24:08 +1100 Subject: [PATCH] Even more unit tests Trying to test all the basic types that coerce covers, and a couple more type parameter and nested cases. --- src/hz.erl | 113 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 10 deletions(-) diff --git a/src/hz.erl b/src/hz.erl index 017ca71..84b1c85 100644 --- a/src/hz.erl +++ b/src/hz.erl @@ -2143,6 +2143,8 @@ eu(N, Size) -> % /v3/debug/crash +%%% Simple coerce/3 tests + try_coerce(Type, Sophia, Fate) -> FateActual = coerce(Type, Sophia, to_fate), SophiaActual = coerce(Type, Fate, from_fate), @@ -2164,26 +2166,63 @@ coerce_int_test() -> {ok, Type} = flatten_opaque_type(integer, #{}), try_coerce(Type, 123, 123). +coerce_address_test() -> + {ok, Type} = flatten_opaque_type(address, #{}), + try_coerce(Type, + "ak_2FTnrGfV8qsfHpaSEHpBrziioCpwwzLqSevHqfxQY3PaAAdARx", + {address, <<164,136,155,90,124,22,40,206,255,76,213,56,238,123, + 167,208,53,78,40,235,2,163,132,36,47,183,228,151,9, + 210,39,214>>}). + +coerce_contract_test() -> + {ok, Type} = flatten_opaque_type(contract, #{}), + try_coerce(Type, + "ct_2FTnrGfV8qsfHpaSEHpBrziioCpwwzLqSevHqfxQY3PaAAdARx", + {contract, <<164,136,155,90,124,22,40,206,255,76,213,56,238,123, + 167,208,53,78,40,235,2,163,132,36,47,183,228,151,9, + 210,39,214>>}). + +coerce_bool_test() -> + {ok, Type} = flatten_opaque_type(boolean, #{}), + try_coerce(Type, true, true), + try_coerce(Type, false, false). + +coerce_string_test() -> + {ok, Type} = flatten_opaque_type(string, #{}), + try_coerce(Type, "hello world", <<"hello world">>). + +coerce_list_test() -> + {ok, Type} = flatten_opaque_type({list, [string]}, #{}), + try_coerce(Type, ["hello world", [65, 32, 65]], [<<"hello world">>, <<65, 32, 65>>]). + +coerce_map_test() -> + {ok, Type} = flatten_opaque_type({map, [string, {list, [integer]}]}, #{}), + try_coerce(Type, #{"a" => "a", "b" => "b"}, #{<<"a">> => "a", <<"b">> => "b"}). + +coerce_tuple_test() -> + {ok, Type} = flatten_opaque_type({tuple, [integer, string]}, #{}), + try_coerce(Type, {123, "456"}, {tuple, {123, <<"456">>}}). + +coerce_variant_test() -> + {ok, Type} = flatten_opaque_type({variant, [{"A", [integer]}, + {"B", [integer, integer]}]}, + #{}), + try_coerce(Type, {"A", 123}, {variant, [1, 2], 0, {123}}), + try_coerce(Type, {"B", 456, 789}, {variant, [1, 2], 1, {456, 789}}). + coerce_record_test() -> {ok, Type} = flatten_opaque_type({record, [{"a", integer}, {"b", integer}]}, #{}), try_coerce(Type, #{"a" => 123, "b" => 456}, {tuple, {123, 456}}). + +%%% Complex AACI paramter and namespace tests + aaci_from_string(String) -> case so_compiler:from_string(String, [{aci, json}]) of {ok, #{aci := ACI}} -> {ok, prepare_aaci(ACI)}; Error -> Error end. -record_substitution_test() -> - Contract = " - contract C = - record pair('t) = { a : 't, b : 't } - entrypoint f(): pair(int) = { a = 1, b = 2 } - ", - {ok, AACI} = aaci_from_string(Contract), - {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), - try_coerce(Output, #{"a" => 123, "b" => 456}, {tuple, {123, 456}}). - namespace_coerce_test() -> Contract = " namespace N = @@ -2196,3 +2235,57 @@ namespace_coerce_test() -> {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), try_coerce(Output, #{"a" => 123, "b" => 456}, {tuple, {123, 456}}). +record_substitution_test() -> + Contract = " + contract C = + record pair('t) = { a : 't, b : 't } + entrypoint f(): pair(int) = { a = 1, b = 2 } + ", + {ok, AACI} = aaci_from_string(Contract), + {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), + try_coerce(Output, #{"a" => 123, "b" => 456}, {tuple, {123, 456}}). + +tuple_substitution_test() -> + Contract = " + contract C = + type triple('t1, 't2) = int * 't1 * 't2 + entrypoint f(): triple(int, string) = (1, 2, \"hello\") + ", + {ok, AACI} = aaci_from_string(Contract), + {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), + try_coerce(Output, {1, 2, "hello"}, {tuple, {1, 2, <<"hello">>}}). + +variant_substitution_test() -> + Contract = " + contract C = + datatype adt('a, 'b) = Left('a, 'b) | Right('b, int) + entrypoint f(): adt(string, int) = Left(\"hi\", 1) + ", + {ok, AACI} = aaci_from_string(Contract), + {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), + try_coerce(Output, {"Left", "hi", 1}, {variant, [2, 2], 0, {<<"hi">>, 1}}), + try_coerce(Output, {"Right", 2, 3}, {variant, [2, 2], 1, {2, 3}}). + +nested_coerce_test() -> + Contract = " + contract C = + type pair('t) = 't * 't + record r = { f1 : pair(int), f2: pair(string) } + entrypoint f(): r = { f1 = (1, 2), f2 = (\"a\", \"b\") } + ", + {ok, AACI} = aaci_from_string(Contract), + {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), + try_coerce(Output, + #{ "f1" => {1, 2}, "f2" => {"a", "b"}}, + {tuple, {{tuple, {1, 2}}, {tuple, {<<"a">>, <<"b">>}}}}). + +state_coerce_test() -> + Contract = " + contract C = + type state = int + entrypoint init(): state = 0 + ", + {ok, AACI} = aaci_from_string(Contract), + {ok, {[], Output}} = aaci_lookup_spec(AACI, "init"), + try_coerce(Output, 0, 0). +