Unsandbox CLI implementations in 42 programming languages for the permacomputer project. Public domain software for code execution across all ecosystems. Languages: Python, JavaScript, Ruby, Go, Rust, C, C++, Java, Kotlin, C#, F#, Haskell, OCaml, Clojure, Scheme, Common Lisp, Erlang, Elixir, D, Nim, Zig, V, Dart, Groovy, Scala, Julia, R, Crystal, Fortran, COBOL, Prolog, Forth, Tcl, Raku, Lua, PHP, Perl, Bash, TypeScript, Objective-C, PowerShell, AWK Includes test suites and service lifecycle tests.
189 lines
5.8 KiB
Erlang
Executable file
189 lines
5.8 KiB
Erlang
Executable file
#!/usr/bin/env escript
|
|
%%! -pa ebin
|
|
|
|
%%% Erlang UN CLI Test Suite
|
|
%%%
|
|
%%% Usage:
|
|
%%% chmod +x test_un_erl.erl
|
|
%%% ./test_un_erl.erl
|
|
%%%
|
|
%%% Or with escript:
|
|
%%% escript test_un_erl.erl
|
|
%%%
|
|
%%% Tests the Erlang UN CLI implementation (un.erl) for:
|
|
%%% 1. Extension detection logic
|
|
%%% 2. API integration (if UNSANDBOX_API_KEY is set)
|
|
%%% 3. End-to-end execution with fib.erl test file
|
|
|
|
-mode(compile).
|
|
|
|
main([]) ->
|
|
io:format("=== Erlang UN CLI Test Suite ===~n~n"),
|
|
|
|
%% Check if API key is set
|
|
case os:getenv("UNSANDBOX_API_KEY") of
|
|
false ->
|
|
io:format("~s⚠ WARNING~s - UNSANDBOX_API_KEY not set, skipping API tests~n~n",
|
|
[yellow(), reset()]);
|
|
_ -> ok
|
|
end,
|
|
|
|
%% Run tests
|
|
Results = [
|
|
print_result("Extension detection", test_extension_detection()),
|
|
print_result("API integration", test_api_integration()),
|
|
print_result("Fibonacci end-to-end test", test_fibonacci())
|
|
],
|
|
|
|
io:format("~n"),
|
|
|
|
%% Summary
|
|
Passed = length([R || R <- Results, R =:= true]),
|
|
Total = length(Results),
|
|
|
|
if
|
|
Passed =:= Total ->
|
|
io:format("~s✓ All tests passed (~p/~p)~s~n",
|
|
[green(), Passed, Total, reset()]),
|
|
halt(0);
|
|
true ->
|
|
io:format("~s✗ Some tests failed (~p/~p passed)~s~n",
|
|
[red(), Passed, Total, reset()]),
|
|
halt(1)
|
|
end.
|
|
|
|
%% ANSI color codes
|
|
green() -> "\033[32m".
|
|
red() -> "\033[31m".
|
|
yellow() -> "\033[33m".
|
|
reset() -> "\033[0m".
|
|
|
|
%% Extension to language mapping (from un.erl)
|
|
ext_to_lang(".hs") -> {ok, "haskell"};
|
|
ext_to_lang(".ml") -> {ok, "ocaml"};
|
|
ext_to_lang(".clj") -> {ok, "clojure"};
|
|
ext_to_lang(".scm") -> {ok, "scheme"};
|
|
ext_to_lang(".lisp") -> {ok, "commonlisp"};
|
|
ext_to_lang(".erl") -> {ok, "erlang"};
|
|
ext_to_lang(".ex") -> {ok, "elixir"};
|
|
ext_to_lang(".py") -> {ok, "python"};
|
|
ext_to_lang(".js") -> {ok, "javascript"};
|
|
ext_to_lang(".rb") -> {ok, "ruby"};
|
|
ext_to_lang(".go") -> {ok, "go"};
|
|
ext_to_lang(".rs") -> {ok, "rust"};
|
|
ext_to_lang(".c") -> {ok, "c"};
|
|
ext_to_lang(".cpp") -> {ok, "cpp"};
|
|
ext_to_lang(".java") -> {ok, "java"};
|
|
ext_to_lang(Ext) -> {error, Ext}.
|
|
|
|
%% Print test result
|
|
print_result(TestName, {pass, _Msg}) ->
|
|
io:format("~s✓ PASS~s - ~s~n", [green(), reset(), TestName]),
|
|
true;
|
|
print_result(TestName, {fail, Msg}) ->
|
|
io:format("~s✗ FAIL~s - ~s~n", [red(), reset(), TestName]),
|
|
io:format(" Error: ~s~n", [Msg]),
|
|
false.
|
|
|
|
%% Test 1: Extension detection
|
|
test_extension_detection() ->
|
|
Tests = [
|
|
{".hs", {ok, "haskell"}},
|
|
{".ml", {ok, "ocaml"}},
|
|
{".clj", {ok, "clojure"}},
|
|
{".scm", {ok, "scheme"}},
|
|
{".lisp", {ok, "commonlisp"}},
|
|
{".erl", {ok, "erlang"}},
|
|
{".ex", {ok, "elixir"}},
|
|
{".py", {ok, "python"}},
|
|
{".js", {ok, "javascript"}},
|
|
{".rb", {ok, "ruby"}}
|
|
],
|
|
|
|
Failures = lists:filter(fun({Ext, Expected}) ->
|
|
ext_to_lang(Ext) =/= Expected
|
|
end, Tests),
|
|
|
|
case Failures of
|
|
[] -> {pass, "All extensions mapped correctly"};
|
|
_ -> {fail, io_lib:format("~p tests failed", [length(Failures)])}
|
|
end.
|
|
|
|
%% Run command and capture output
|
|
run_command(Cmd) ->
|
|
Port = open_port({spawn, Cmd}, [stream, exit_status, use_stdio,
|
|
stderr_to_stdout, in, eof]),
|
|
get_data(Port, []).
|
|
|
|
get_data(Port, Acc) ->
|
|
receive
|
|
{Port, {data, Bytes}} ->
|
|
get_data(Port, [Acc|Bytes]);
|
|
{Port, eof} ->
|
|
Port ! {self(), close},
|
|
receive
|
|
{Port, closed} -> true
|
|
end,
|
|
receive
|
|
{'EXIT', Port, _} -> ok
|
|
after 1000 -> ok
|
|
end,
|
|
get_data(Port, Acc);
|
|
{Port, {exit_status, Status}} ->
|
|
{Status, lists:flatten(Acc)}
|
|
after 5000 ->
|
|
{1, lists:flatten(Acc)}
|
|
end.
|
|
|
|
%% Test 2: API integration
|
|
test_api_integration() ->
|
|
case os:getenv("UNSANDBOX_API_KEY") of
|
|
false -> {pass, "Skipped - no API key"};
|
|
_ ->
|
|
try
|
|
%% Create a simple test file
|
|
TestCode = "-module(test).\n-export([main/0]).\nmain() -> io:format(\"test~n\").\n",
|
|
ok = file:write_file("/tmp/test_un_erl_api.erl", TestCode),
|
|
|
|
%% Run the CLI
|
|
{Status, Output} = run_command("./un.erl /tmp/test_un_erl_api.erl 2>&1"),
|
|
|
|
%% Check if it executed successfully
|
|
case {Status, string:str(Output, "test")} of
|
|
{0, Pos} when Pos > 0 ->
|
|
{pass, "API integration successful"};
|
|
_ ->
|
|
{fail, io_lib:format("API call failed: ~p, output: ~s",
|
|
[Status, Output])}
|
|
end
|
|
catch
|
|
_:Error ->
|
|
{fail, io_lib:format("Exception: ~p", [Error])}
|
|
end
|
|
end.
|
|
|
|
%% Test 3: Functional test with fib.erl
|
|
test_fibonacci() ->
|
|
case os:getenv("UNSANDBOX_API_KEY") of
|
|
false -> {pass, "Skipped - no API key"};
|
|
_ ->
|
|
try
|
|
%% Check if fib.erl exists
|
|
FibPath = "../test/fib.erl",
|
|
|
|
%% Run the CLI with fib.erl
|
|
{Status, Output} = run_command("./un.erl " ++ FibPath ++ " 2>&1"),
|
|
|
|
%% Check if output contains expected fibonacci result
|
|
case {Status, string:str(Output, "fib(10) = 55")} of
|
|
{0, Pos} when Pos > 0 ->
|
|
{pass, "Fibonacci test successful"};
|
|
_ ->
|
|
{fail, io_lib:format("Fibonacci test failed: ~p, output: ~s",
|
|
[Status, Output])}
|
|
end
|
|
catch
|
|
_:Error ->
|
|
{fail, io_lib:format("Exception: ~p", [Error])}
|
|
end
|
|
end.
|