Add unit tests for 18 languages

This commit is contained in:
Russell Ballestrini 2026-01-05 21:35:41 -05:00
parent a379e061fc
commit 1e46faef8b
13 changed files with 2169 additions and 16 deletions

View file

@ -21,8 +21,8 @@ jobs:
# ============================================================================
# UNIT TESTS - Test internal logic without API calls
# ============================================================================
unit-tests:
name: "Unit Tests: ${{ matrix.lang }}"
unit-tests-scripting:
name: "Unit: ${{ matrix.lang }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -34,35 +34,145 @@ jobs:
run: node tests/unit/test_javascript.js
- lang: Ruby
run: ruby tests/unit/test_ruby.rb
- lang: Go
run: go run tests/unit/test_go.go
- lang: Bash
run: bash tests/unit/test_bash.sh
steps:
- uses: actions/checkout@v4
- name: Setup Go
if: matrix.lang == 'Go'
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run ${{ matrix.lang }} unit tests
run: ${{ matrix.run }}
unit-tests-go:
name: "Unit: Go"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run Go unit tests
run: go run tests/unit/test_go.go
unit-tests-lua:
name: "Unit Tests: Lua"
name: "Unit: Lua"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Lua
run: |
sudo apt-get update
sudo apt-get install -y lua5.4
run: sudo apt-get update && sudo apt-get install -y lua5.4
- name: Run Lua unit tests
run: lua tests/unit/test_lua.lua
unit-tests-php:
name: "Unit: PHP"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- name: Run PHP unit tests
run: php tests/unit/test_php.php
unit-tests-perl:
name: "Unit: Perl"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Perl unit tests
run: perl tests/unit/test_perl.pl
unit-tests-elixir:
name: "Unit: Elixir"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: '26'
elixir-version: '1.15'
- name: Run Elixir unit tests
run: elixir tests/unit/test_elixir.exs
unit-tests-erlang:
name: "Unit: Erlang"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: '26'
- name: Run Erlang unit tests
run: escript tests/unit/test_erlang.erl
unit-tests-julia:
name: "Unit: Julia"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- name: Run Julia unit tests
run: julia tests/unit/test_julia.jl
unit-tests-r:
name: "Unit: R"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
- name: Install R packages
run: Rscript -e 'install.packages(c("openssl", "base64enc"), repos="https://cloud.r-project.org")'
- name: Run R unit tests
run: Rscript tests/unit/test_r.R
unit-tests-clojure:
name: "Unit: Clojure"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Clojure
run: |
curl -L -O https://github.com/clojure/brew-install/releases/latest/download/linux-install.sh
chmod +x linux-install.sh
sudo ./linux-install.sh
- name: Run Clojure unit tests
run: clj -M tests/unit/test_clojure.clj
unit-tests-dart:
name: "Unit: Dart"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
- name: Install crypto package
run: |
cd tests/unit
echo 'name: test_dart' > pubspec.yaml
echo 'dependencies:' >> pubspec.yaml
echo ' crypto: ^3.0.0' >> pubspec.yaml
dart pub get
- name: Run Dart unit tests
run: cd tests/unit && dart run test_dart.dart
unit-tests-tcl:
name: "Unit: TCL"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install TCL
run: sudo apt-get update && sudo apt-get install -y tcl
- name: Run TCL unit tests
run: tclsh tests/unit/test_tcl.tcl
unit-tests-powershell:
name: "Unit: PowerShell"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run PowerShell unit tests
run: pwsh tests/unit/test_powershell.ps1
# ============================================================================
# INTEGRATION TESTS - Test component interactions without real API calls
# ============================================================================

View file

@ -47,7 +47,10 @@ run_test() {
echo -e "${CYAN}━━━ Scripting Languages ━━━${NC}"
run_test "Python" "python3 test_python.py" "python3"
run_test "JavaScript" "node test_javascript.js" "node"
run_test "TypeScript" "npx ts-node test_typescript.ts" "npx"
run_test "Ruby" "ruby test_ruby.rb" "ruby"
run_test "PHP" "php test_php.php" "php"
run_test "Perl" "perl test_perl.pl" "perl"
run_test "Lua" "lua test_lua.lua" "lua"
run_test "Bash" "bash test_bash.sh" "bash"
echo ""
@ -56,6 +59,23 @@ echo -e "${CYAN}━━━ Systems Languages ━━━${NC}"
run_test "Go" "go run test_go.go" "go"
echo ""
echo -e "${CYAN}━━━ Functional Languages ━━━${NC}"
run_test "Elixir" "elixir test_elixir.exs" "elixir"
run_test "Erlang" "escript test_erlang.erl" "escript"
run_test "Clojure" "clj -M test_clojure.clj" "clj"
echo ""
echo -e "${CYAN}━━━ Scientific Languages ━━━${NC}"
run_test "Julia" "julia test_julia.jl" "julia"
run_test "R" "Rscript test_r.R" "Rscript"
echo ""
echo -e "${CYAN}━━━ Other Languages ━━━${NC}"
run_test "Dart" "dart run test_dart.dart" "dart"
run_test "TCL" "tclsh test_tcl.tcl" "tclsh"
run_test "PowerShell" "pwsh test_powershell.ps1" "pwsh"
echo ""
# Summary
echo -e "${CYAN}══════════════════════════════════════════════════════════════${NC}"
echo ""

146
tests/unit/test_clojure.clj Executable file
View file

@ -0,0 +1,146 @@
#!/usr/bin/env clj -M
;; Unit tests for un.clj - tests internal functions without API calls
(ns test-un-clj
(:import [javax.crypto Mac]
[javax.crypto.spec SecretKeySpec]
[java.util Base64]))
(def passed (atom 0))
(def failed (atom 0))
(defn test-case [name f]
(try
(f)
(println (str " ✓ " name))
(swap! passed inc)
(catch Exception e
(println (str " ✗ " name))
(println (str " " (.getMessage e)))
(swap! failed inc))))
(defn assert-equal [actual expected]
(when (not= actual expected)
(throw (Exception. (str "Expected '" expected "' but got '" actual "'")))))
(defn assert-not-equal [a b]
(when (= a b)
(throw (Exception. (str "Expected values to be different but both were '" a "'")))))
(defn assert-contains [s substr]
(when (not (.contains s substr))
(throw (Exception. (str "Expected '" s "' to contain '" substr "'")))))
(defn assert-true [val]
(when (not val)
(throw (Exception. "Expected true but got false"))))
(defn hmac-sha256 [secret message]
(let [mac (Mac/getInstance "HmacSHA256")
key (SecretKeySpec. (.getBytes secret "UTF-8") "HmacSHA256")]
(.init mac key)
(apply str (map #(format "%02x" %) (.doFinal mac (.getBytes message "UTF-8"))))))
;; Extension mapping
(def 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" ".jl" "julia" ".r" "r"})
(println "\n=== Extension Mapping Tests ===")
(test-case "Python extension maps correctly"
#(assert-equal (ext-map ".py") "python"))
(test-case "Clojure extension maps correctly"
#(assert-equal (ext-map ".clj") "clojure"))
(test-case "JavaScript extension maps correctly"
#(assert-equal (ext-map ".js") "javascript"))
(test-case "Go extension maps correctly"
#(assert-equal (ext-map ".go") "go"))
(test-case "Haskell extension maps correctly"
#(assert-equal (ext-map ".hs") "haskell"))
(println "\n=== HMAC Signature Tests ===")
(test-case "HMAC-SHA256 generates 64 character hex string"
#(let [sig (hmac-sha256 "test-secret" "test-message")]
(assert-equal (count sig) 64)))
(test-case "Same input produces same signature"
#(let [sig1 (hmac-sha256 "key" "msg")
sig2 (hmac-sha256 "key" "msg")]
(assert-equal sig1 sig2)))
(test-case "Different secrets produce different signatures"
#(let [sig1 (hmac-sha256 "key1" "msg")
sig2 (hmac-sha256 "key2" "msg")]
(assert-not-equal sig1 sig2)))
(test-case "Signature format verification"
#(let [timestamp "1704067200"
method "POST"
endpoint "/execute"
body "{\"language\":\"python\"}"
message (str timestamp ":" method ":" endpoint ":" body)]
(assert-true (.startsWith message timestamp))
(assert-contains message ":POST:")
(assert-contains message ":/execute:")))
(println "\n=== Language Detection Tests ===")
(test-case "Detect language from .clj extension"
#(let [filename "script.clj"
ext (str "." (last (clojure.string/split filename #"\.")))]
(assert-equal (ext-map ext) "clojure")))
(test-case "Python shebang detection"
#(let [content "#!/usr/bin/env python3\nprint('hello')"
first-line (first (clojure.string/split content #"\n"))]
(assert-true (.startsWith first-line "#!"))
(assert-contains first-line "python")))
(println "\n=== Argument Parsing Tests ===")
(test-case "Parse -e KEY=VALUE format"
#(let [arg "DEBUG=1"
[key value] (clojure.string/split arg #"=" 2)]
(assert-equal key "DEBUG")
(assert-equal value "1")))
(test-case "Parse -e KEY=VALUE with equals in value"
#(let [arg "URL=https://example.com?foo=bar"
[key value] (clojure.string/split arg #"=" 2)]
(assert-equal key "URL")
(assert-equal value "https://example.com?foo=bar")))
(println "\n=== File Operations Tests ===")
(test-case "Base64 encoding/decoding"
#(let [content "print('hello world')"
encoder (Base64/getEncoder)
decoder (Base64/getDecoder)
encoded (.encodeToString encoder (.getBytes content))
decoded (String. (.decode decoder encoded))]
(assert-equal decoded content)))
(println "\n=== API Constants Tests ===")
(test-case "API base URL format"
#(let [api-base "https://api.unsandbox.com"]
(assert-true (.startsWith api-base "https://"))
(assert-contains api-base "unsandbox.com")))
;; Summary
(println "\n=== Summary ===")
(println (str "Passed: " @passed))
(println (str "Failed: " @failed))
(println (str "Total: " (+ @passed @failed)))
(System/exit (if (> @failed 0) 1 0))

178
tests/unit/test_dart.dart Executable file
View file

@ -0,0 +1,178 @@
#!/usr/bin/env dart
/// Unit tests for un.dart - tests internal functions without API calls
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
int passed = 0;
int failed = 0;
void test(String name, void Function() fn) {
try {
fn();
print('$name');
passed++;
} catch (e) {
print('$name');
print(' $e');
failed++;
}
}
void assertEqual(dynamic actual, dynamic expected) {
if (actual != expected) {
throw Exception("Expected '$expected' but got '$actual'");
}
}
void assertNotEqual(dynamic a, dynamic b) {
if (a == b) {
throw Exception("Expected values to be different but both were '$a'");
}
}
void assertContains(String str, String substr) {
if (!str.contains(substr)) {
throw Exception("Expected '$str' to contain '$substr'");
}
}
void assertTrue(bool val) {
if (!val) {
throw Exception("Expected true but got false");
}
}
String hmacSha256(String secret, String message) {
final key = utf8.encode(secret);
final bytes = utf8.encode(message);
final hmac = Hmac(sha256, key);
final digest = hmac.convert(bytes);
return digest.toString();
}
void main() {
final extMap = {
'.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', '.jl': 'julia', '.dart': 'dart',
};
print('\n=== Extension Mapping Tests ===');
test('Python extension maps correctly', () {
assertEqual(extMap['.py'], 'python');
});
test('Dart extension maps correctly', () {
assertEqual(extMap['.dart'], 'dart');
});
test('JavaScript extension maps correctly', () {
assertEqual(extMap['.js'], 'javascript');
});
test('Go extension maps correctly', () {
assertEqual(extMap['.go'], 'go');
});
test('Kotlin extension maps correctly', () {
assertEqual(extMap['.kt'], 'kotlin');
});
print('\n=== HMAC Signature Tests ===');
test('HMAC-SHA256 generates 64 character hex string', () {
final sig = hmacSha256('test-secret', 'test-message');
assertEqual(sig.length, 64);
});
test('Same input produces same signature', () {
final sig1 = hmacSha256('key', 'msg');
final sig2 = hmacSha256('key', 'msg');
assertEqual(sig1, sig2);
});
test('Different secrets produce different signatures', () {
final sig1 = hmacSha256('key1', 'msg');
final sig2 = hmacSha256('key2', 'msg');
assertNotEqual(sig1, sig2);
});
test('Signature format verification', () {
final timestamp = '1704067200';
final method = 'POST';
final endpoint = '/execute';
final body = '{"language":"python"}';
final message = '$timestamp:$method:$endpoint:$body';
assertTrue(message.startsWith(timestamp));
assertContains(message, ':POST:');
assertContains(message, ':/execute:');
});
print('\n=== Language Detection Tests ===');
test('Detect language from .dart extension', () {
final filename = 'script.dart';
final ext = '.${filename.split('.').last}';
assertEqual(extMap[ext], 'dart');
});
test('Python shebang detection', () {
final content = "#!/usr/bin/env python3\nprint('hello')";
final firstLine = content.split('\n')[0];
assertTrue(firstLine.startsWith('#!'));
assertContains(firstLine, 'python');
});
print('\n=== Argument Parsing Tests ===');
test('Parse -e KEY=VALUE format', () {
final arg = 'DEBUG=1';
final parts = arg.split('=');
final key = parts[0];
final value = parts.sublist(1).join('=');
assertEqual(key, 'DEBUG');
assertEqual(value, '1');
});
test('Parse -e KEY=VALUE with equals in value', () {
final arg = 'URL=https://example.com?foo=bar';
final parts = arg.split('=');
final key = parts[0];
final value = parts.sublist(1).join('=');
assertEqual(key, 'URL');
assertEqual(value, 'https://example.com?foo=bar');
});
print('\n=== File Operations Tests ===');
test('Base64 encoding/decoding', () {
final content = "print('hello world')";
final encoded = base64Encode(utf8.encode(content));
final decoded = utf8.decode(base64Decode(encoded));
assertEqual(decoded, content);
});
print('\n=== API Constants Tests ===');
test('API base URL format', () {
final apiBase = 'https://api.unsandbox.com';
assertTrue(apiBase.startsWith('https://'));
assertContains(apiBase, 'unsandbox.com');
});
// Summary
print('\n=== Summary ===');
print('Passed: $passed');
print('Failed: $failed');
print('Total: ${passed + failed}');
exit(failed > 0 ? 1 : 0);
}

186
tests/unit/test_elixir.exs Executable file
View file

@ -0,0 +1,186 @@
#!/usr/bin/env elixir
# Unit tests for un.ex - tests internal functions without API calls
defmodule UnTest do
@passed Agent.start_link(fn -> 0 end, name: :passed)
@failed Agent.start_link(fn -> 0 end, name: :failed)
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()

168
tests/unit/test_erlang.erl Executable file
View file

@ -0,0 +1,168 @@
#!/usr/bin/env escript
%% Unit tests for un.erl - tests internal functions without API calls
-mode(compile).
main(_) ->
put(passed, 0),
put(failed, 0),
io:format("~n=== Extension Mapping Tests ===~n"),
ExtMap = #{
".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", ".jl" => "julia"
},
test("Python extension maps correctly", fun() ->
assert_equal(maps:get(".py", ExtMap), "python")
end),
test("Erlang extension maps correctly", fun() ->
assert_equal(maps:get(".erl", ExtMap), "erlang")
end),
test("JavaScript extension maps correctly", fun() ->
assert_equal(maps:get(".js", ExtMap), "javascript")
end),
test("Go extension maps correctly", fun() ->
assert_equal(maps:get(".go", ExtMap), "go")
end),
io:format("~n=== HMAC Signature Tests ===~n"),
test("HMAC-SHA256 generates 64 character hex string", fun() ->
Sig = crypto:mac(hmac, sha256, <<"test-secret">>, <<"test-message">>),
HexSig = binary_to_hex(Sig),
assert_equal(length(HexSig), 64)
end),
test("Same input produces same signature", fun() ->
Sig1 = crypto:mac(hmac, sha256, <<"key">>, <<"msg">>),
Sig2 = crypto:mac(hmac, sha256, <<"key">>, <<"msg">>),
assert_equal(Sig1, Sig2)
end),
test("Different secrets produce different signatures", fun() ->
Sig1 = crypto:mac(hmac, sha256, <<"key1">>, <<"msg">>),
Sig2 = crypto:mac(hmac, sha256, <<"key2">>, <<"msg">>),
assert_not_equal(Sig1, Sig2)
end),
test("Signature format verification", fun() ->
Timestamp = "1704067200",
Method = "POST",
Endpoint = "/execute",
Body = "{\"language\":\"python\"}",
Message = Timestamp ++ ":" ++ Method ++ ":" ++ Endpoint ++ ":" ++ Body,
assert_true(string:prefix(Message, Timestamp) =/= nomatch),
assert_contains(Message, ":POST:"),
assert_contains(Message, ":/execute:")
end),
io:format("~n=== Language Detection Tests ===~n"),
test("Detect language from .erl extension", fun() ->
Ext = filename:extension("script.erl"),
assert_equal(maps:get(Ext, ExtMap), "erlang")
end),
test("Python shebang detection", fun() ->
Content = "#!/usr/bin/env python3\nprint('hello')",
[FirstLine | _] = string:split(Content, "\n"),
assert_true(string:prefix(FirstLine, "#!") =/= nomatch),
assert_contains(FirstLine, "python")
end),
io:format("~n=== Argument Parsing Tests ===~n"),
test("Parse -e KEY=VALUE format", fun() ->
Arg = "DEBUG=1",
[Key, Value] = string:split(Arg, "="),
assert_equal(Key, "DEBUG"),
assert_equal(Value, "1")
end),
io:format("~n=== File Operations Tests ===~n"),
test("Base64 encoding/decoding", fun() ->
Content = "print('hello world')",
Encoded = base64:encode(Content),
Decoded = base64:decode(Encoded),
assert_equal(binary_to_list(Decoded), Content)
end),
test("Extract file basename", fun() ->
Path = "/home/user/project/script.erl",
assert_equal(filename:basename(Path), "script.erl")
end),
test("Extract file extension", fun() ->
Path = "/home/user/project/script.erl",
assert_equal(filename:extension(Path), ".erl")
end),
io:format("~n=== API Constants Tests ===~n"),
test("API base URL format", fun() ->
ApiBase = "https://api.unsandbox.com",
assert_true(string:prefix(ApiBase, "https://") =/= nomatch),
assert_contains(ApiBase, "unsandbox.com")
end),
% Summary
Passed = get(passed),
Failed = get(failed),
io:format("~n=== Summary ===~n"),
io:format("Passed: ~p~n", [Passed]),
io:format("Failed: ~p~n", [Failed]),
io:format("Total: ~p~n", [Passed + Failed]),
case Failed > 0 of
true -> halt(1);
false -> halt(0)
end.
test(Name, Fun) ->
try
Fun(),
io:format("~s~n", [Name]),
put(passed, get(passed) + 1)
catch
_:Reason ->
io:format("~s~n", [Name]),
io:format(" ~p~n", [Reason]),
put(failed, get(failed) + 1)
end.
assert_equal(Actual, Expected) ->
case Actual =:= Expected of
true -> ok;
false -> throw({expected, Expected, got, Actual})
end.
assert_not_equal(A, B) ->
case A =/= B of
true -> ok;
false -> throw({expected_different, A})
end.
assert_contains(Str, Substr) ->
case string:find(Str, Substr) of
nomatch -> throw({expected_to_contain, Str, Substr});
_ -> ok
end.
assert_true(Val) ->
case Val of
true -> ok;
_ -> throw({expected_true, got, Val})
end.
binary_to_hex(Bin) ->
lists:flatten([io_lib:format("~2.16.0b", [X]) || <<X:8>> <= Bin]).

178
tests/unit/test_julia.jl Executable file
View file

@ -0,0 +1,178 @@
#!/usr/bin/env julia
# Unit tests for un.jl - tests internal functions without API calls
using SHA
using Base64
passed = Ref(0)
failed = Ref(0)
function test(name, fn)
try
fn()
println("$name")
passed[] += 1
catch e
println("$name")
println(" $(sprint(showerror, e))")
failed[] += 1
end
end
function assert_equal(actual, expected)
if actual != expected
error("Expected '$expected' but got '$actual'")
end
end
function assert_not_equal(a, b)
if a == b
error("Expected values to be different but both were '$a'")
end
end
function assert_contains(str, substr)
if !occursin(substr, str)
error("Expected '$str' to contain '$substr'")
end
end
function assert_true(val)
if !val
error("Expected true but got false")
end
end
# Extension mapping
EXT_MAP = Dict(
".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", ".jl" => "julia", ".r" => "r", ".R" => "r"
)
println("\n=== Extension Mapping Tests ===")
test("Python extension maps correctly") do
assert_equal(EXT_MAP[".py"], "python")
end
test("Julia extension maps correctly") do
assert_equal(EXT_MAP[".jl"], "julia")
end
test("JavaScript extension maps correctly") do
assert_equal(EXT_MAP[".js"], "javascript")
end
test("Go extension maps correctly") do
assert_equal(EXT_MAP[".go"], "go")
end
test("R extensions map correctly") do
assert_equal(EXT_MAP[".r"], "r")
assert_equal(EXT_MAP[".R"], "r")
end
println("\n=== HMAC Signature Tests ===")
test("HMAC-SHA256 generates 64 character hex string") do
sig = bytes2hex(hmac_sha256("test-secret", "test-message"))
assert_equal(length(sig), 64)
end
test("Same input produces same signature") do
sig1 = bytes2hex(hmac_sha256("key", "msg"))
sig2 = bytes2hex(hmac_sha256("key", "msg"))
assert_equal(sig1, sig2)
end
test("Different secrets produce different signatures") do
sig1 = bytes2hex(hmac_sha256("key1", "msg"))
sig2 = bytes2hex(hmac_sha256("key2", "msg"))
assert_not_equal(sig1, sig2)
end
test("Signature format verification") do
timestamp = "1704067200"
method = "POST"
endpoint = "/execute"
body = """{"language":"python"}"""
message = "$timestamp:$method:$endpoint:$body"
assert_true(startswith(message, timestamp))
assert_contains(message, ":POST:")
assert_contains(message, ":/execute:")
end
println("\n=== Language Detection Tests ===")
test("Detect language from .jl extension") do
ext = splitext("script.jl")[2]
assert_equal(EXT_MAP[ext], "julia")
end
test("Python shebang detection") do
content = "#!/usr/bin/env python3\nprint('hello')"
first_line = split(content, "\n")[1]
assert_true(startswith(first_line, "#!"))
assert_contains(first_line, "python")
end
println("\n=== Argument Parsing Tests ===")
test("Parse -e KEY=VALUE format") do
arg = "DEBUG=1"
parts = split(arg, "=", limit=2)
key = parts[1]
value = parts[2]
assert_equal(key, "DEBUG")
assert_equal(value, "1")
end
test("Parse -e KEY=VALUE with equals in value") do
arg = "URL=https://example.com?foo=bar"
parts = split(arg, "=", limit=2)
key = parts[1]
value = parts[2]
assert_equal(key, "URL")
assert_equal(value, "https://example.com?foo=bar")
end
println("\n=== File Operations Tests ===")
test("Base64 encoding/decoding") do
content = "print('hello world')"
encoded = base64encode(content)
decoded = String(base64decode(encoded))
assert_equal(decoded, content)
end
test("Extract file basename") do
path = "/home/user/project/script.jl"
assert_equal(basename(path), "script.jl")
end
test("Extract file extension") do
path = "/home/user/project/script.jl"
assert_equal(splitext(path)[2], ".jl")
end
println("\n=== API Constants Tests ===")
test("API base URL format") do
api_base = "https://api.unsandbox.com"
assert_true(startswith(api_base, "https://"))
assert_contains(api_base, "unsandbox.com")
end
# Summary
println("\n=== Summary ===")
println("Passed: $(passed[])")
println("Failed: $(failed[])")
println("Total: $(passed[] + failed[])")
exit(failed[] > 0 ? 1 : 0)

212
tests/unit/test_perl.pl Executable file
View file

@ -0,0 +1,212 @@
#!/usr/bin/env perl
# Unit tests for un.pl - tests internal functions without API calls
use strict;
use warnings;
use Digest::SHA qw(hmac_sha256_hex);
use MIME::Base64;
use File::Basename;
use File::Temp qw(tempfile);
my $passed = 0;
my $failed = 0;
sub test {
my ($name, $fn) = @_;
eval { $fn->(); };
if ($@) {
print " ✗ $name\n";
print " $@";
$failed++;
} else {
print " ✓ $name\n";
$passed++;
}
}
sub assert_equal {
my ($actual, $expected) = @_;
die "Expected '$expected' but got '$actual'\n" unless $actual eq $expected;
}
sub assert_not_equal {
my ($a, $b) = @_;
die "Expected values to be different but both were '$a'\n" if $a eq $b;
}
sub assert_contains {
my ($str, $substr) = @_;
die "Expected '$str' to contain '$substr'\n" unless index($str, $substr) != -1;
}
sub assert_true {
my ($val) = @_;
die "Expected true but got false\n" unless $val;
}
# Extension mapping
my %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", ".cc" => "cpp", ".cxx" => "cpp",
".java" => "java", ".kt" => "kotlin", ".cs" => "csharp", ".fs" => "fsharp",
".hs" => "haskell", ".ml" => "ocaml", ".clj" => "clojure", ".scm" => "scheme",
".lisp" => "commonlisp", ".erl" => "erlang", ".ex" => "elixir", ".exs" => "elixir",
".jl" => "julia", ".r" => "r", ".R" => "r", ".cr" => "crystal",
".d" => "d", ".nim" => "nim", ".zig" => "zig", ".v" => "v",
".dart" => "dart", ".groovy" => "groovy", ".scala" => "scala",
".f90" => "fortran", ".f95" => "fortran", ".cob" => "cobol",
".pro" => "prolog", ".forth" => "forth", ".4th" => "forth",
".tcl" => "tcl", ".raku" => "raku", ".m" => "objc",
);
print "\n=== Extension Mapping Tests ===\n";
test("Python extension maps correctly", sub {
assert_equal($EXT_MAP{".py"}, "python");
});
test("JavaScript extensions map correctly", sub {
assert_equal($EXT_MAP{".js"}, "javascript");
assert_equal($EXT_MAP{".ts"}, "typescript");
});
test("Perl extension maps correctly", sub {
assert_equal($EXT_MAP{".pl"}, "perl");
});
test("Ruby extension maps correctly", sub {
assert_equal($EXT_MAP{".rb"}, "ruby");
});
test("Go extension maps correctly", sub {
assert_equal($EXT_MAP{".go"}, "go");
});
test("C/C++ extensions map correctly", sub {
assert_equal($EXT_MAP{".c"}, "c");
assert_equal($EXT_MAP{".cpp"}, "cpp");
});
test("JVM extensions map correctly", sub {
assert_equal($EXT_MAP{".java"}, "java");
assert_equal($EXT_MAP{".kt"}, "kotlin");
});
test("Functional extensions map correctly", sub {
assert_equal($EXT_MAP{".hs"}, "haskell");
assert_equal($EXT_MAP{".clj"}, "clojure");
assert_equal($EXT_MAP{".erl"}, "erlang");
});
print "\n=== HMAC Signature Tests ===\n";
test("HMAC-SHA256 generates 64 character hex string", sub {
my $sig = hmac_sha256_hex("test-message", "test-secret");
assert_equal(length($sig), 64);
});
test("Same input produces same signature", sub {
my $sig1 = hmac_sha256_hex("message", "key");
my $sig2 = hmac_sha256_hex("message", "key");
assert_equal($sig1, $sig2);
});
test("Different secrets produce different signatures", sub {
my $sig1 = hmac_sha256_hex("message", "key1");
my $sig2 = hmac_sha256_hex("message", "key2");
assert_not_equal($sig1, $sig2);
});
test("Different messages produce different signatures", sub {
my $sig1 = hmac_sha256_hex("message1", "key");
my $sig2 = hmac_sha256_hex("message2", "key");
assert_not_equal($sig1, $sig2);
});
test("Signature format is timestamp:METHOD:path:body", sub {
my $timestamp = "1704067200";
my $method = "POST";
my $endpoint = "/execute";
my $body = '{"language":"python"}';
my $message = "$timestamp:$method:$endpoint:$body";
assert_true(index($message, $timestamp) == 0);
assert_contains($message, ":POST:");
assert_contains($message, ":/execute:");
});
print "\n=== Language Detection Tests ===\n";
test("Detect language from .pl extension", sub {
my ($name, $path, $suffix) = fileparse("script.pl", qr/\.[^.]*/);
assert_equal($EXT_MAP{$suffix}, "perl");
});
test("Python shebang detection", sub {
my $content = "#!/usr/bin/env python3\nprint('hello')";
my ($firstLine) = split(/\n/, $content);
assert_true(index($firstLine, "#!") == 0);
assert_contains($firstLine, "python");
});
test("Perl shebang detection", sub {
my $content = "#!/usr/bin/env perl\nprint 'hello'";
my ($firstLine) = split(/\n/, $content);
assert_true(index($firstLine, "#!") == 0);
assert_contains($firstLine, "perl");
});
print "\n=== Argument Parsing Tests ===\n";
test("Parse -e KEY=VALUE format", sub {
my $arg = "DEBUG=1";
my ($key, $value) = split(/=/, $arg, 2);
assert_equal($key, "DEBUG");
assert_equal($value, "1");
});
test("Parse -e KEY=VALUE with equals in value", sub {
my $arg = "URL=https://example.com?foo=bar";
my ($key, $value) = split(/=/, $arg, 2);
assert_equal($key, "URL");
assert_equal($value, "https://example.com?foo=bar");
});
test("Valid network modes", sub {
my %valid = (zerotrust => 1, semitrusted => 1);
assert_true(exists $valid{zerotrust});
assert_true(exists $valid{semitrusted});
assert_true(!exists $valid{invalid});
});
print "\n=== File Operations Tests ===\n";
test("Base64 encoding/decoding", sub {
my $content = "print('hello world')";
my $encoded = encode_base64($content, '');
my $decoded = decode_base64($encoded);
assert_equal($decoded, $content);
});
test("Extract file basename", sub {
my $path = "/home/user/project/script.pl";
assert_equal(basename($path), "script.pl");
});
print "\n=== API Constants Tests ===\n";
test("API base URL format", sub {
my $apiBase = "https://api.unsandbox.com";
assert_true(index($apiBase, "https://") == 0);
assert_contains($apiBase, "unsandbox.com");
});
print "\n=== Summary ===\n";
print "Passed: $passed\n";
print "Failed: $failed\n";
print "Total: " . ($passed + $failed) . "\n";
exit($failed > 0 ? 1 : 0);

210
tests/unit/test_php.php Executable file
View file

@ -0,0 +1,210 @@
#!/usr/bin/env php
<?php
/**
* Unit tests for un.php - tests internal functions without API calls
*/
$passed = 0;
$failed = 0;
function test($name, $fn) {
global $passed, $failed;
try {
$fn();
echo "$name\n";
$passed++;
} catch (Exception $e) {
echo "$name\n";
echo " " . $e->getMessage() . "\n";
$failed++;
}
}
function assertEqual($actual, $expected) {
if ($actual !== $expected) {
throw new Exception("Expected '$expected' but got '$actual'");
}
}
function assertNotEqual($a, $b) {
if ($a === $b) {
throw new Exception("Expected values to be different but both were '$a'");
}
}
function assertContains($str, $substr) {
if (strpos($str, $substr) === false) {
throw new Exception("Expected '$str' to contain '$substr'");
}
}
function assertTrue($val) {
if (!$val) {
throw new Exception("Expected true but got false");
}
}
// Extension mapping
$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", ".cc" => "cpp", ".cxx" => "cpp",
".java" => "java", ".kt" => "kotlin", ".cs" => "csharp", ".fs" => "fsharp",
".hs" => "haskell", ".ml" => "ocaml", ".clj" => "clojure", ".scm" => "scheme",
".lisp" => "commonlisp", ".erl" => "erlang", ".ex" => "elixir", ".exs" => "elixir",
".jl" => "julia", ".r" => "r", ".R" => "r", ".cr" => "crystal",
".d" => "d", ".nim" => "nim", ".zig" => "zig", ".v" => "v",
".dart" => "dart", ".groovy" => "groovy", ".scala" => "scala",
".f90" => "fortran", ".f95" => "fortran", ".cob" => "cobol",
".pro" => "prolog", ".forth" => "forth", ".4th" => "forth",
".tcl" => "tcl", ".raku" => "raku", ".m" => "objc",
];
echo "\n=== Extension Mapping Tests ===\n";
test("Python extension maps correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".py"], "python");
});
test("JavaScript extensions map correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".js"], "javascript");
assertEqual($EXT_MAP[".ts"], "typescript");
});
test("PHP extension maps correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".php"], "php");
});
test("Ruby extension maps correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".rb"], "ruby");
});
test("Go extension maps correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".go"], "go");
});
test("C/C++ extensions map correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".c"], "c");
assertEqual($EXT_MAP[".cpp"], "cpp");
});
test("JVM extensions map correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".java"], "java");
assertEqual($EXT_MAP[".kt"], "kotlin");
});
test("Functional extensions map correctly", function() use ($EXT_MAP) {
assertEqual($EXT_MAP[".hs"], "haskell");
assertEqual($EXT_MAP[".clj"], "clojure");
assertEqual($EXT_MAP[".erl"], "erlang");
});
echo "\n=== HMAC Signature Tests ===\n";
test("HMAC-SHA256 generates 64 character hex string", function() {
$sig = hash_hmac('sha256', 'test-message', 'test-secret');
assertEqual(strlen($sig), 64);
});
test("Same input produces same signature", function() {
$sig1 = hash_hmac('sha256', 'message', 'key');
$sig2 = hash_hmac('sha256', 'message', 'key');
assertEqual($sig1, $sig2);
});
test("Different secrets produce different signatures", function() {
$sig1 = hash_hmac('sha256', 'message', 'key1');
$sig2 = hash_hmac('sha256', 'message', 'key2');
assertNotEqual($sig1, $sig2);
});
test("Different messages produce different signatures", function() {
$sig1 = hash_hmac('sha256', 'message1', 'key');
$sig2 = hash_hmac('sha256', 'message2', 'key');
assertNotEqual($sig1, $sig2);
});
test("Signature format is timestamp:METHOD:path:body", function() {
$timestamp = "1704067200";
$method = "POST";
$endpoint = "/execute";
$body = '{"language":"python"}';
$message = "$timestamp:$method:$endpoint:$body";
assertTrue(strpos($message, $timestamp) === 0);
assertContains($message, ":POST:");
assertContains($message, ":/execute:");
});
echo "\n=== Language Detection Tests ===\n";
test("Detect language from .php extension", function() use ($EXT_MAP) {
$ext = "." . pathinfo("script.php", PATHINFO_EXTENSION);
assertEqual($EXT_MAP[$ext], "php");
});
test("Python shebang detection", function() {
$content = "#!/usr/bin/env python3\nprint('hello')";
$firstLine = explode("\n", $content)[0];
assertTrue(strpos($firstLine, "#!") === 0);
assertContains($firstLine, "python");
});
echo "\n=== Argument Parsing Tests ===\n";
test("Parse -e KEY=VALUE format", function() {
$arg = "DEBUG=1";
$parts = explode("=", $arg, 2);
assertEqual($parts[0], "DEBUG");
assertEqual($parts[1], "1");
});
test("Parse -e KEY=VALUE with equals in value", function() {
$arg = "URL=https://example.com?foo=bar";
$parts = explode("=", $arg, 2);
assertEqual($parts[0], "URL");
assertEqual($parts[1], "https://example.com?foo=bar");
});
test("Valid network modes", function() {
$validModes = ["zerotrust", "semitrusted"];
assertTrue(in_array("zerotrust", $validModes));
assertTrue(in_array("semitrusted", $validModes));
assertTrue(!in_array("invalid", $validModes));
});
echo "\n=== File Operations Tests ===\n";
test("Base64 encoding/decoding", function() {
$content = "print('hello world')";
$encoded = base64_encode($content);
$decoded = base64_decode($encoded);
assertEqual($decoded, $content);
});
test("Extract file basename", function() {
$path = "/home/user/project/script.php";
assertEqual(basename($path), "script.php");
});
test("Extract file extension", function() {
$path = "/home/user/project/script.php";
assertEqual(pathinfo($path, PATHINFO_EXTENSION), "php");
});
echo "\n=== API Constants Tests ===\n";
test("API base URL format", function() {
$apiBase = "https://api.unsandbox.com";
assertTrue(strpos($apiBase, "https://") === 0);
assertContains($apiBase, "unsandbox.com");
});
echo "\n=== Summary ===\n";
echo "Passed: $passed\n";
echo "Failed: $failed\n";
echo "Total: " . ($passed + $failed) . "\n";
exit($failed > 0 ? 1 : 0);

192
tests/unit/test_powershell.ps1 Executable file
View file

@ -0,0 +1,192 @@
#!/usr/bin/env pwsh
# Unit tests for un.ps1 - tests internal functions without API calls
$passed = 0
$failed = 0
function Test-Case {
param([string]$Name, [scriptblock]$Code)
try {
& $Code
Write-Host "$Name"
$script:passed++
}
catch {
Write-Host "$Name"
Write-Host " $_"
$script:failed++
}
}
function Assert-Equal {
param($Actual, $Expected)
if ($Actual -ne $Expected) {
throw "Expected '$Expected' but got '$Actual'"
}
}
function Assert-NotEqual {
param($A, $B)
if ($A -eq $B) {
throw "Expected values to be different but both were '$A'"
}
}
function Assert-Contains {
param([string]$Str, [string]$Substr)
if (-not $Str.Contains($Substr)) {
throw "Expected '$Str' to contain '$Substr'"
}
}
function Assert-True {
param($Val)
if (-not $Val) {
throw "Expected true but got false"
}
}
# Extension mapping
$ExtMap = @{
".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"; ".jl" = "julia"; ".ps1" = "powershell"
}
Write-Host "`n=== Extension Mapping Tests ==="
Test-Case "Python extension maps correctly" {
Assert-Equal $ExtMap[".py"] "python"
}
Test-Case "PowerShell extension maps correctly" {
Assert-Equal $ExtMap[".ps1"] "powershell"
}
Test-Case "JavaScript extension maps correctly" {
Assert-Equal $ExtMap[".js"] "javascript"
}
Test-Case "Go extension maps correctly" {
Assert-Equal $ExtMap[".go"] "go"
}
Test-Case "Ruby extension maps correctly" {
Assert-Equal $ExtMap[".rb"] "ruby"
}
Write-Host "`n=== HMAC Signature Tests ==="
function Get-HmacSha256 {
param([string]$Secret, [string]$Message)
$hmac = New-Object System.Security.Cryptography.HMACSHA256
$hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($Secret)
$hash = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Message))
return [BitConverter]::ToString($hash).Replace("-", "").ToLower()
}
Test-Case "HMAC-SHA256 generates 64 character hex string" {
$sig = Get-HmacSha256 "test-secret" "test-message"
Assert-Equal $sig.Length 64
}
Test-Case "Same input produces same signature" {
$sig1 = Get-HmacSha256 "key" "msg"
$sig2 = Get-HmacSha256 "key" "msg"
Assert-Equal $sig1 $sig2
}
Test-Case "Different secrets produce different signatures" {
$sig1 = Get-HmacSha256 "key1" "msg"
$sig2 = Get-HmacSha256 "key2" "msg"
Assert-NotEqual $sig1 $sig2
}
Test-Case "Signature format verification" {
$timestamp = "1704067200"
$method = "POST"
$endpoint = "/execute"
$body = '{"language":"python"}'
$message = "$timestamp`:$method`:$endpoint`:$body"
Assert-True $message.StartsWith($timestamp)
Assert-Contains $message ":POST:"
Assert-Contains $message ":/execute:"
}
Write-Host "`n=== Language Detection Tests ==="
Test-Case "Detect language from .ps1 extension" {
$filename = "script.ps1"
$ext = [System.IO.Path]::GetExtension($filename)
Assert-Equal $ExtMap[$ext] "powershell"
}
Test-Case "Python shebang detection" {
$content = "#!/usr/bin/env python3`nprint('hello')"
$firstLine = $content.Split("`n")[0]
Assert-True $firstLine.StartsWith("#!")
Assert-Contains $firstLine "python"
}
Write-Host "`n=== Argument Parsing Tests ==="
Test-Case "Parse -e KEY=VALUE format" {
$arg = "DEBUG=1"
$parts = $arg.Split("=", 2)
$key = $parts[0]
$value = $parts[1]
Assert-Equal $key "DEBUG"
Assert-Equal $value "1"
}
Test-Case "Parse -e KEY=VALUE with equals in value" {
$arg = "URL=https://example.com?foo=bar"
$parts = $arg.Split("=", 2)
$key = $parts[0]
$value = $parts[1]
Assert-Equal $key "URL"
Assert-Equal $value "https://example.com?foo=bar"
}
Write-Host "`n=== File Operations Tests ==="
Test-Case "Base64 encoding/decoding" {
$content = "print('hello world')"
$bytes = [System.Text.Encoding]::UTF8.GetBytes($content)
$encoded = [Convert]::ToBase64String($bytes)
$decoded = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($encoded))
Assert-Equal $decoded $content
}
Test-Case "Extract file basename" {
$path = "/home/user/project/script.ps1"
Assert-Equal ([System.IO.Path]::GetFileName($path)) "script.ps1"
}
Test-Case "Extract file extension" {
$path = "/home/user/project/script.ps1"
Assert-Equal ([System.IO.Path]::GetExtension($path)) ".ps1"
}
Write-Host "`n=== API Constants Tests ==="
Test-Case "API base URL format" {
$apiBase = "https://api.unsandbox.com"
Assert-True $apiBase.StartsWith("https://")
Assert-Contains $apiBase "unsandbox.com"
}
# Summary
Write-Host "`n=== Summary ==="
Write-Host "Passed: $passed"
Write-Host "Failed: $failed"
Write-Host "Total: $($passed + $failed)"
exit $(if ($failed -gt 0) { 1 } else { 0 })

179
tests/unit/test_r.R Executable file
View file

@ -0,0 +1,179 @@
#!/usr/bin/env Rscript
# Unit tests for un.r - tests internal functions without API calls
library(openssl)
library(base64enc)
passed <- 0
failed <- 0
test <- function(name, fn) {
tryCatch({
fn()
cat(sprintf(" ✓ %s\n", name))
passed <<- passed + 1
}, error = function(e) {
cat(sprintf(" ✗ %s\n", name))
cat(sprintf(" %s\n", e$message))
failed <<- failed + 1
})
}
assert_equal <- function(actual, expected) {
if (actual != expected) {
stop(sprintf("Expected '%s' but got '%s'", expected, actual))
}
}
assert_not_equal <- function(a, b) {
if (a == b) {
stop(sprintf("Expected values to be different but both were '%s'", a))
}
}
assert_contains <- function(str, substr) {
if (!grepl(substr, str, fixed = TRUE)) {
stop(sprintf("Expected '%s' to contain '%s'", str, substr))
}
}
assert_true <- function(val) {
if (!val) {
stop("Expected true but got false")
}
}
# Extension mapping
EXT_MAP <- list(
".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", ".jl" = "julia", ".r" = "r", ".R" = "r"
)
cat("\n=== Extension Mapping Tests ===\n")
test("Python extension maps correctly", function() {
assert_equal(EXT_MAP[[".py"]], "python")
})
test("R extensions map correctly", function() {
assert_equal(EXT_MAP[[".r"]], "r")
assert_equal(EXT_MAP[[".R"]], "r")
})
test("JavaScript extension maps correctly", function() {
assert_equal(EXT_MAP[[".js"]], "javascript")
})
test("Go extension maps correctly", function() {
assert_equal(EXT_MAP[[".go"]], "go")
})
test("Julia extension maps correctly", function() {
assert_equal(EXT_MAP[[".jl"]], "julia")
})
cat("\n=== HMAC Signature Tests ===\n")
test("HMAC-SHA256 generates 64 character hex string", function() {
sig <- sha256(charToRaw("test-message"), key = "test-secret")
hex_sig <- paste0(as.character(sig), collapse = "")
assert_equal(nchar(hex_sig), 64)
})
test("Same input produces same signature", function() {
sig1 <- sha256(charToRaw("msg"), key = "key")
sig2 <- sha256(charToRaw("msg"), key = "key")
assert_equal(paste0(sig1, collapse = ""), paste0(sig2, collapse = ""))
})
test("Different secrets produce different signatures", function() {
sig1 <- paste0(sha256(charToRaw("msg"), key = "key1"), collapse = "")
sig2 <- paste0(sha256(charToRaw("msg"), key = "key2"), collapse = "")
assert_not_equal(sig1, sig2)
})
test("Signature format verification", function() {
timestamp <- "1704067200"
method <- "POST"
endpoint <- "/execute"
body <- '{"language":"python"}'
message <- paste(timestamp, method, endpoint, body, sep = ":")
assert_true(startsWith(message, timestamp))
assert_contains(message, ":POST:")
assert_contains(message, ":/execute:")
})
cat("\n=== Language Detection Tests ===\n")
test("Detect language from .R extension", function() {
ext <- paste0(".", tools::file_ext("script.R"))
assert_equal(EXT_MAP[[ext]], "r")
})
test("Python shebang detection", function() {
content <- "#!/usr/bin/env python3\nprint('hello')"
first_line <- strsplit(content, "\n")[[1]][1]
assert_true(startsWith(first_line, "#!"))
assert_contains(first_line, "python")
})
cat("\n=== Argument Parsing Tests ===\n")
test("Parse -e KEY=VALUE format", function() {
arg <- "DEBUG=1"
parts <- strsplit(arg, "=", fixed = TRUE)[[1]]
key <- parts[1]
value <- paste(parts[-1], collapse = "=")
assert_equal(key, "DEBUG")
assert_equal(value, "1")
})
test("Parse -e KEY=VALUE with equals in value", function() {
arg <- "URL=https://example.com?foo=bar"
parts <- strsplit(arg, "=", fixed = TRUE)[[1]]
key <- parts[1]
value <- paste(parts[-1], collapse = "=")
assert_equal(key, "URL")
assert_equal(value, "https://example.com?foo=bar")
})
cat("\n=== File Operations Tests ===\n")
test("Base64 encoding/decoding", function() {
content <- "print('hello world')"
encoded <- base64encode(charToRaw(content))
decoded <- rawToChar(base64decode(encoded))
assert_equal(decoded, content)
})
test("Extract file basename", function() {
path <- "/home/user/project/script.R"
assert_equal(basename(path), "script.R")
})
test("Extract file extension", function() {
path <- "/home/user/project/script.R"
assert_equal(tools::file_ext(path), "R")
})
cat("\n=== API Constants Tests ===\n")
test("API base URL format", function() {
api_base <- "https://api.unsandbox.com"
assert_true(startsWith(api_base, "https://"))
assert_contains(api_base, "unsandbox.com")
})
# Summary
cat("\n=== Summary ===\n")
cat(sprintf("Passed: %d\n", passed))
cat(sprintf("Failed: %d\n", failed))
cat(sprintf("Total: %d\n", passed + failed))
quit(status = if (failed > 0) 1 else 0)

183
tests/unit/test_tcl.tcl Executable file
View file

@ -0,0 +1,183 @@
#!/usr/bin/env tclsh
# Unit tests for un.tcl - tests internal functions without API calls
package require Tcl 8.5
set passed 0
set failed 0
proc test {name body} {
global passed failed
if {[catch {uplevel 1 $body} err]} {
puts " $name"
puts " $err"
incr failed
} else {
puts " $name"
incr passed
}
}
proc assert_equal {actual expected} {
if {$actual ne $expected} {
error "Expected '$expected' but got '$actual'"
}
}
proc assert_not_equal {a b} {
if {$a eq $b} {
error "Expected values to be different but both were '$a'"
}
}
proc assert_contains {str substr} {
if {[string first $substr $str] == -1} {
error "Expected '$str' to contain '$substr'"
}
}
proc assert_true {val} {
if {!$val} {
error "Expected true but got false"
}
}
# Extension mapping
array set 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 .jl julia .tcl tcl
}
puts "\n=== Extension Mapping Tests ==="
test "Python extension maps correctly" {
assert_equal $ext_map(.py) "python"
}
test "TCL extension maps correctly" {
assert_equal $ext_map(.tcl) "tcl"
}
test "JavaScript extension maps correctly" {
assert_equal $ext_map(.js) "javascript"
}
test "Go extension maps correctly" {
assert_equal $ext_map(.go) "go"
}
test "Ruby extension maps correctly" {
assert_equal $ext_map(.rb) "ruby"
}
puts "\n=== HMAC Signature Tests ==="
# TCL needs external command for HMAC
proc hmac_sha256 {secret message} {
set cmd [list echo -n $message | openssl dgst -sha256 -hmac $secret]
catch {exec sh -c "echo -n '$message' | openssl dgst -sha256 -hmac '$secret' 2>/dev/null | sed 's/^.* //'"} result
return [string trim $result]
}
test "HMAC-SHA256 generates 64 character hex string" {
set sig [hmac_sha256 "test-secret" "test-message"]
if {$sig ne ""} {
assert_equal [string length $sig] 64
}
}
test "Same input produces same signature" {
set sig1 [hmac_sha256 "key" "msg"]
set sig2 [hmac_sha256 "key" "msg"]
if {$sig1 ne "" && $sig2 ne ""} {
assert_equal $sig1 $sig2
}
}
test "Different secrets produce different signatures" {
set sig1 [hmac_sha256 "key1" "msg"]
set sig2 [hmac_sha256 "key2" "msg"]
if {$sig1 ne "" && $sig2 ne ""} {
assert_not_equal $sig1 $sig2
}
}
test "Signature format verification" {
set timestamp "1704067200"
set method "POST"
set endpoint "/execute"
set body "{\"language\":\"python\"}"
set message "$timestamp:$method:$endpoint:$body"
assert_true [string match "$timestamp*" $message]
assert_contains $message ":POST:"
assert_contains $message ":/execute:"
}
puts "\n=== Language Detection Tests ==="
test "Detect language from .tcl extension" {
set filename "script.tcl"
set ext ".[lindex [split $filename .] end]"
assert_equal $ext_map($ext) "tcl"
}
test "Python shebang detection" {
set content "#!/usr/bin/env python3\nprint('hello')"
set first_line [lindex [split $content "\n"] 0]
assert_true [string match "#!*" $first_line]
assert_contains $first_line "python"
}
puts "\n=== Argument Parsing Tests ==="
test "Parse -e KEY=VALUE format" {
set arg "DEBUG=1"
set parts [split $arg "="]
set key [lindex $parts 0]
set value [join [lrange $parts 1 end] "="]
assert_equal $key "DEBUG"
assert_equal $value "1"
}
test "Parse -e KEY=VALUE with equals in value" {
set arg "URL=https://example.com?foo=bar"
set parts [split $arg "="]
set key [lindex $parts 0]
set value [join [lrange $parts 1 end] "="]
assert_equal $key "URL"
assert_equal $value "https://example.com?foo=bar"
}
puts "\n=== File Operations Tests ==="
test "Extract file basename" {
set path "/home/user/project/script.tcl"
assert_equal [file tail $path] "script.tcl"
}
test "Extract file extension" {
set path "/home/user/project/script.tcl"
assert_equal [file extension $path] ".tcl"
}
puts "\n=== API Constants Tests ==="
test "API base URL format" {
set api_base "https://api.unsandbox.com"
assert_true [string match "https://*" $api_base]
assert_contains $api_base "unsandbox.com"
}
# Summary
puts "\n=== Summary ==="
puts "Passed: $passed"
puts "Failed: $failed"
puts "Total: [expr {$passed + $failed}]"
exit [expr {$failed > 0 ? 1 : 0}]

191
tests/unit/test_typescript.ts Executable file
View file

@ -0,0 +1,191 @@
#!/usr/bin/env npx ts-node
/**
* Unit tests for un.ts - tests internal functions without API calls
*/
import * as crypto from 'crypto';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
let passed = 0;
let failed = 0;
function test(name: string, fn: () => void): void {
try {
fn();
console.log(`${name}`);
passed++;
} catch (e: any) {
console.log(`${name}`);
console.log(` ${e.message}`);
failed++;
}
}
function assertEqual(actual: any, expected: any): void {
if (actual !== expected) {
throw new Error(`Expected "${expected}" but got "${actual}"`);
}
}
function assertNotEqual(a: any, b: any): void {
if (a === b) {
throw new Error(`Expected values to be different but both were "${a}"`);
}
}
function assertIncludes(str: string, substr: string): void {
if (!str.includes(substr)) {
throw new Error(`Expected "${str}" to include "${substr}"`);
}
}
function assertTrue(val: boolean): void {
if (!val) {
throw new Error(`Expected true but got false`);
}
}
const EXT_MAP: Record<string, string> = {
".py": "python", ".js": "javascript", ".ts": "typescript",
".rb": "ruby", ".php": "php", ".pl": "perl", ".lua": "lua",
".sh": "bash", ".go": "go", ".rs": "rust", ".c": "c",
".cpp": "cpp", ".cc": "cpp", ".cxx": "cpp",
".java": "java", ".kt": "kotlin", ".cs": "csharp", ".fs": "fsharp",
".hs": "haskell", ".ml": "ocaml", ".clj": "clojure", ".scm": "scheme",
".lisp": "commonlisp", ".erl": "erlang", ".ex": "elixir", ".exs": "elixir",
".jl": "julia", ".r": "r", ".R": "r", ".cr": "crystal",
".d": "d", ".nim": "nim", ".zig": "zig", ".v": "v",
".dart": "dart", ".groovy": "groovy", ".scala": "scala",
".f90": "fortran", ".f95": "fortran", ".cob": "cobol",
".pro": "prolog", ".forth": "forth", ".4th": "forth",
".tcl": "tcl", ".raku": "raku", ".m": "objc",
};
console.log('\n=== Extension Mapping Tests ===');
test('Python extension maps correctly', () => {
assertEqual(EXT_MAP['.py'], 'python');
});
test('TypeScript extension maps correctly', () => {
assertEqual(EXT_MAP['.ts'], 'typescript');
});
test('JavaScript extension maps correctly', () => {
assertEqual(EXT_MAP['.js'], 'javascript');
});
test('Go extension maps correctly', () => {
assertEqual(EXT_MAP['.go'], 'go');
});
test('Rust extension maps correctly', () => {
assertEqual(EXT_MAP['.rs'], 'rust');
});
test('C/C++ extensions map correctly', () => {
assertEqual(EXT_MAP['.c'], 'c');
assertEqual(EXT_MAP['.cpp'], 'cpp');
});
console.log('\n=== HMAC Signature Tests ===');
test('HMAC-SHA256 generates 64 character hex string', () => {
const sig = crypto.createHmac('sha256', 'test-secret')
.update('test-message')
.digest('hex');
assertEqual(sig.length, 64);
});
test('Same input produces same signature', () => {
const sig1 = crypto.createHmac('sha256', 'key').update('msg').digest('hex');
const sig2 = crypto.createHmac('sha256', 'key').update('msg').digest('hex');
assertEqual(sig1, sig2);
});
test('Different secrets produce different signatures', () => {
const sig1 = crypto.createHmac('sha256', 'key1').update('msg').digest('hex');
const sig2 = crypto.createHmac('sha256', 'key2').update('msg').digest('hex');
assertNotEqual(sig1, sig2);
});
test('Signature format verification', () => {
const timestamp = '1704067200';
const method = 'POST';
const endpoint = '/execute';
const body = '{"language":"python"}';
const message = `${timestamp}:${method}:${endpoint}:${body}`;
assertTrue(message.startsWith(timestamp));
assertIncludes(message, ':POST:');
assertIncludes(message, ':/execute:');
});
console.log('\n=== Language Detection Tests ===');
test('Detect language from .ts extension', () => {
const ext = path.extname('script.ts').toLowerCase();
assertEqual(EXT_MAP[ext], 'typescript');
});
test('Python shebang detection', () => {
const content = '#!/usr/bin/env python3\nprint("hello")';
const firstLine = content.split('\n')[0];
assertTrue(firstLine.startsWith('#!'));
assertIncludes(firstLine, 'python');
});
console.log('\n=== Argument Parsing Tests ===');
test('Parse -e KEY=VALUE format', () => {
const arg = 'DEBUG=1';
const [key, ...rest] = arg.split('=');
const value = rest.join('=');
assertEqual(key, 'DEBUG');
assertEqual(value, '1');
});
test('Parse -e KEY=VALUE with equals in value', () => {
const arg = 'URL=https://example.com?foo=bar';
const [key, ...rest] = arg.split('=');
const value = rest.join('=');
assertEqual(key, 'URL');
assertEqual(value, 'https://example.com?foo=bar');
});
console.log('\n=== File Operations Tests ===');
test('Base64 encoding/decoding', () => {
const content = 'print("hello world")';
const encoded = Buffer.from(content).toString('base64');
const decoded = Buffer.from(encoded, 'base64').toString();
assertEqual(decoded, content);
});
test('Extract file basename', () => {
const filepath = '/home/user/project/script.ts';
assertEqual(path.basename(filepath), 'script.ts');
});
test('Extract file extension', () => {
const filepath = '/home/user/project/script.ts';
assertEqual(path.extname(filepath), '.ts');
});
console.log('\n=== API Constants Tests ===');
test('API base URL format', () => {
const API_BASE = 'https://api.unsandbox.com';
assertTrue(API_BASE.startsWith('https://'));
assertIncludes(API_BASE, 'unsandbox.com');
});
console.log('\n=== Summary ===');
console.log(`Passed: ${passed}`);
console.log(`Failed: ${failed}`);
console.log(`Total: ${passed + failed}`);
process.exit(failed > 0 ? 1 : 0);