Repo scaffolding (LICENSE, Makefile, pyproject.toml, README) matching unfeed conventions. Flat package layout, ruff config, Unlicense. ETF codec covers the subset needed for gen_call against an Elixir node: small/int/big_int, atom_utf8 (legacy atom_ext on decode), binary, nil, list, small/large tuple, new_pid, newer_reference. Booleans round-trip as atoms true/false; Python None as atom nil; str encodes to utf-8 binary to match Elixir convention. Golden vectors were generated from real Erlang term_to_binary/1 output (generator script at docs/etf_vectors.erl). Decode tests verify wire compatibility; round-trip tests verify encoder consistency. make all green: 58 passed, lint clean. Next phases tracked in docs/ROADMAP.md (EPMD, handshake, channel, gen_call, TLS, unfeed integration).
47 lines
1.4 KiB
Erlang
47 lines
1.4 KiB
Erlang
%% Generator for the golden ETF vectors used in tests/test_etf.py.
|
|
%% Re-run when adding new test cases:
|
|
%%
|
|
%% erlc -o /tmp docs/etf_vectors.erl
|
|
%% erl -noshell -pa /tmp -eval 'etf_vectors:main([]), init:stop().'
|
|
%% cat /tmp/etf_vectors.txt
|
|
%%
|
|
-module(etf_vectors).
|
|
-export([main/1]).
|
|
|
|
main(_) ->
|
|
Terms = [
|
|
{small_int_0, 0},
|
|
{small_int_42, 42},
|
|
{small_int_255, 255},
|
|
{int_256, 256},
|
|
{int_neg_1, -1},
|
|
{int_max32, 2147483647},
|
|
{int_min32, -2147483648},
|
|
{big_pos, 9999999999999999},
|
|
{big_neg, -9999999999999999},
|
|
{atom_hello, hello},
|
|
{atom_true, true},
|
|
{atom_false, false},
|
|
{atom_nil, nil},
|
|
{atom_unicode, 'привет'},
|
|
{binary_empty, <<>>},
|
|
{binary_hi, <<"hi">>},
|
|
{binary_utf8, <<"héllo"/utf8>>},
|
|
{tuple_empty, {}},
|
|
{tuple_pair, {ok, <<"value">>}},
|
|
{tuple_triple, {1, 2, 3}},
|
|
{list_empty, []},
|
|
{list_ints, [1, 2, 3]},
|
|
{list_mixed, [hello, <<"world">>, 42]},
|
|
{nested, {gen_call, [{node, 'wallet@cammy'}], {get_balance, xmr}}}
|
|
],
|
|
Out = [
|
|
io_lib:format("~s|~s~n", [atom_to_list(N), bin_to_hex(term_to_binary(T))])
|
|
|| {N, T} <- Terms
|
|
],
|
|
ok = file:write_file("/tmp/etf_vectors.txt", iolist_to_binary(Out)).
|
|
|
|
bin_to_hex(B) ->
|
|
<< <<(hex(N div 16)), (hex(N rem 16))>> || <<N>> <= B >>.
|
|
hex(N) when N < 10 -> $0 + N;
|
|
hex(N) -> $a + N - 10.
|