- Elixir: Remove unused module attributes @passed/@failed - Go: Add cache: false to all setup-go actions (no go.sum file)
183 lines
5.3 KiB
Elixir
Executable file
183 lines
5.3 KiB
Elixir
Executable file
#!/usr/bin/env elixir
|
|
# Unit tests for un.ex - tests internal functions without API calls
|
|
|
|
defmodule UnTest do
|
|
def run do
|
|
Agent.start_link(fn -> 0 end, name: :passed)
|
|
Agent.start_link(fn -> 0 end, name: :failed)
|
|
|
|
IO.puts("\n=== Extension Mapping Tests ===")
|
|
|
|
ext_map = %{
|
|
".py" => "python", ".js" => "javascript", ".ts" => "typescript",
|
|
".rb" => "ruby", ".php" => "php", ".pl" => "perl", ".lua" => "lua",
|
|
".sh" => "bash", ".go" => "go", ".rs" => "rust", ".c" => "c",
|
|
".cpp" => "cpp", ".java" => "java", ".kt" => "kotlin",
|
|
".hs" => "haskell", ".clj" => "clojure", ".erl" => "erlang",
|
|
".ex" => "elixir", ".exs" => "elixir", ".jl" => "julia"
|
|
}
|
|
|
|
test("Python extension maps correctly", fn ->
|
|
assert_equal(ext_map[".py"], "python")
|
|
end)
|
|
|
|
test("Elixir extensions map correctly", fn ->
|
|
assert_equal(ext_map[".ex"], "elixir")
|
|
assert_equal(ext_map[".exs"], "elixir")
|
|
end)
|
|
|
|
test("JavaScript extension maps correctly", fn ->
|
|
assert_equal(ext_map[".js"], "javascript")
|
|
end)
|
|
|
|
test("Go extension maps correctly", fn ->
|
|
assert_equal(ext_map[".go"], "go")
|
|
end)
|
|
|
|
test("Erlang extension maps correctly", fn ->
|
|
assert_equal(ext_map[".erl"], "erlang")
|
|
end)
|
|
|
|
IO.puts("\n=== HMAC Signature Tests ===")
|
|
|
|
test("HMAC-SHA256 generates 64 character hex string", fn ->
|
|
sig = :crypto.mac(:hmac, :sha256, "test-secret", "test-message")
|
|
|> Base.encode16(case: :lower)
|
|
assert_equal(String.length(sig), 64)
|
|
end)
|
|
|
|
test("Same input produces same signature", fn ->
|
|
sig1 = :crypto.mac(:hmac, :sha256, "key", "msg") |> Base.encode16(case: :lower)
|
|
sig2 = :crypto.mac(:hmac, :sha256, "key", "msg") |> Base.encode16(case: :lower)
|
|
assert_equal(sig1, sig2)
|
|
end)
|
|
|
|
test("Different secrets produce different signatures", fn ->
|
|
sig1 = :crypto.mac(:hmac, :sha256, "key1", "msg") |> Base.encode16(case: :lower)
|
|
sig2 = :crypto.mac(:hmac, :sha256, "key2", "msg") |> Base.encode16(case: :lower)
|
|
assert_not_equal(sig1, sig2)
|
|
end)
|
|
|
|
test("Signature format verification", fn ->
|
|
timestamp = "1704067200"
|
|
method = "POST"
|
|
endpoint = "/execute"
|
|
body = ~s({"language":"python"})
|
|
|
|
message = "#{timestamp}:#{method}:#{endpoint}:#{body}"
|
|
|
|
assert_true(String.starts_with?(message, timestamp))
|
|
assert_contains(message, ":POST:")
|
|
assert_contains(message, ":/execute:")
|
|
end)
|
|
|
|
IO.puts("\n=== Language Detection Tests ===")
|
|
|
|
test("Detect language from .exs extension", fn ->
|
|
ext = Path.extname("script.exs")
|
|
assert_equal(ext_map[ext], "elixir")
|
|
end)
|
|
|
|
test("Python shebang detection", fn ->
|
|
content = "#!/usr/bin/env python3\nprint('hello')"
|
|
[first_line | _] = String.split(content, "\n")
|
|
assert_true(String.starts_with?(first_line, "#!"))
|
|
assert_contains(first_line, "python")
|
|
end)
|
|
|
|
IO.puts("\n=== Argument Parsing Tests ===")
|
|
|
|
test("Parse -e KEY=VALUE format", fn ->
|
|
arg = "DEBUG=1"
|
|
[key | rest] = String.split(arg, "=", parts: 2)
|
|
value = Enum.join(rest, "=")
|
|
assert_equal(key, "DEBUG")
|
|
assert_equal(value, "1")
|
|
end)
|
|
|
|
test("Parse -e KEY=VALUE with equals in value", fn ->
|
|
arg = "URL=https://example.com?foo=bar"
|
|
[key | rest] = String.split(arg, "=", parts: 2)
|
|
value = Enum.join(rest, "=")
|
|
assert_equal(key, "URL")
|
|
assert_equal(value, "https://example.com?foo=bar")
|
|
end)
|
|
|
|
IO.puts("\n=== File Operations Tests ===")
|
|
|
|
test("Base64 encoding/decoding", fn ->
|
|
content = "print('hello world')"
|
|
encoded = Base.encode64(content)
|
|
{:ok, decoded} = Base.decode64(encoded)
|
|
assert_equal(decoded, content)
|
|
end)
|
|
|
|
test("Extract file basename", fn ->
|
|
path = "/home/user/project/script.exs"
|
|
assert_equal(Path.basename(path), "script.exs")
|
|
end)
|
|
|
|
test("Extract file extension", fn ->
|
|
path = "/home/user/project/script.exs"
|
|
assert_equal(Path.extname(path), ".exs")
|
|
end)
|
|
|
|
IO.puts("\n=== API Constants Tests ===")
|
|
|
|
test("API base URL format", fn ->
|
|
api_base = "https://api.unsandbox.com"
|
|
assert_true(String.starts_with?(api_base, "https://"))
|
|
assert_contains(api_base, "unsandbox.com")
|
|
end)
|
|
|
|
# Summary
|
|
passed = Agent.get(:passed, & &1)
|
|
failed = Agent.get(:failed, & &1)
|
|
|
|
IO.puts("\n=== Summary ===")
|
|
IO.puts("Passed: #{passed}")
|
|
IO.puts("Failed: #{failed}")
|
|
IO.puts("Total: #{passed + failed}")
|
|
|
|
if failed > 0, do: System.halt(1), else: System.halt(0)
|
|
end
|
|
|
|
defp test(name, fun) do
|
|
try do
|
|
fun.()
|
|
IO.puts(" ✓ #{name}")
|
|
Agent.update(:passed, &(&1 + 1))
|
|
rescue
|
|
e ->
|
|
IO.puts(" ✗ #{name}")
|
|
IO.puts(" #{Exception.message(e)}")
|
|
Agent.update(:failed, &(&1 + 1))
|
|
end
|
|
end
|
|
|
|
defp assert_equal(actual, expected) do
|
|
if actual != expected do
|
|
raise "Expected '#{expected}' but got '#{actual}'"
|
|
end
|
|
end
|
|
|
|
defp assert_not_equal(a, b) do
|
|
if a == b do
|
|
raise "Expected values to be different but both were '#{a}'"
|
|
end
|
|
end
|
|
|
|
defp assert_contains(str, substr) do
|
|
unless String.contains?(str, substr) do
|
|
raise "Expected '#{str}' to contain '#{substr}'"
|
|
end
|
|
end
|
|
|
|
defp assert_true(val) do
|
|
unless val do
|
|
raise "Expected true but got false"
|
|
end
|
|
end
|
|
end
|
|
|
|
UnTest.run()
|