sophia/test/so_scan_tests.erl
Craig Everett dbab49936d
All checks were successful
Sophia Tests / tests (push) Successful in 48m54s
Renaming and preparing to remove oracles (#985)
A few references to oracles still remain, but they have been removed as a feature, at least.

Reviewed-on: #985
Reviewed-by: Ulf Wiger <ulfwiger@qpq.swiss>
Co-authored-by: Craig Everett <zxq9@zxq9.com>
Co-committed-by: Craig Everett <zxq9@zxq9.com>
2025-03-13 12:53:01 +09:00

86 lines
2.6 KiB
Erlang

-module(so_scan_tests).
-include_lib("eunit/include/eunit.hrl").
empty_contract_test_() ->
{foreach,
fun() ->
ok
end,
fun(_) ->
ok
end,
[{"Scan an empty contract.",
fun() ->
Text = " ",
{ok, []} = so_scan:scan(Text),
ok
end}
]}.
all_tokens_test_() ->
{foreach, fun() -> ok end,
fun(_) -> ok end,
[{"Check that we can scan all tokens.",
fun() ->
Tokens = all_tokens(),
Text = string:join(lists:map(fun show_token/1, Tokens), " "),
io:format("~s\n", [Text]),
{ok, Tokens1} = so_scan:scan(Text),
true = compare_tokens(Tokens, Tokens1),
ok
end}
]}.
all_tokens() ->
Lit = fun(T) -> {T, 1} end,
Tok = fun(T, V) -> {T, 1, V} end,
Hash = list_to_binary([ I * 8 || I <- lists:seq(0, 31) ]),
%% Symbols
lists:map(Lit, [',', '.', ';', '|', ':', '(', ')', '[', ']', '{', '}']) ++
%% Operators
lists:map(Lit, ['=', '==', '!=', '>', '<', '>=', '=<', '-', '+', '++', '*', '/', mod,
':', '::', '->', '=>', '||', '&&', '!', 'band', 'bor', 'bxor', 'bnot' ,'<<', '>>']) ++
%% Keywords
lists:map(Lit, [contract, type, 'let', switch]) ++
%% Comment token (not an actual token), just for tests
[{comment, 0, "// *Comment!\"\n"},
{comment, 0, "/* bla /* bla bla */*/"}] ++
%% Literals
[ Lit(true), Lit(false)
, Tok(id, "foo"), Tok(id, "_"), Tok(con, "Foo")
, Tok(bytes, Hash)
, Tok(int, 1234567890), Tok(hex, 9876543210)
, Tok(string, <<"bla\"\\\b\e\f\n\r\t\vbla">>)
].
compare_tokens([], []) -> true;
compare_tokens([{T, _} | Ts1], [{T, _} | Ts2]) ->
compare_tokens(Ts1, Ts2);
compare_tokens([{T, _, V} | Ts1], [{T, _, V} | Ts2]) ->
compare_tokens(Ts1, Ts2);
compare_tokens([{comment, _, _} | Ts1], Ts2) ->
compare_tokens(Ts1, Ts2);
compare_tokens(Ts1, Ts2) ->
case length(Ts1) == length(Ts2) of
true ->
{token_mismatch, [ {expected, T1, got, T2} || {T1, T2} <- lists:zip(Ts1, Ts2), T1 /= T2]};
false ->
{token_mismatch, {expected, Ts1, got, Ts2}}
end.
fmt(X) -> fmt("~p", X).
fmt(Fmt, X) -> lists:flatten(io_lib:format(Fmt, [X])).
show_token({T, _}) -> atom_to_list(T);
show_token({id, _, X}) -> X;
show_token({con, _, C}) -> C;
show_token({param, _, P}) -> "@" ++ P;
show_token({string, _, S}) -> fmt(binary_to_list(S));
show_token({int, _, N}) -> fmt(N);
show_token({hex, _, N}) -> fmt("0x~.16b", N);
show_token({bytes, _, <<N:256>>}) -> fmt("#~64.16.0b", N);
show_token({comment, _, S}) -> S;
show_token({_, _, _}) -> "TODO".