un-inception/tests/test_un_lua.lua
Russell Ballestrini 2b35819393 Initial commit: 42 UN CLI implementations
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.
2025-12-23 09:57:08 -05:00

226 lines
7.5 KiB
Lua
Executable file

#!/usr/bin/env lua
-- Test suite for UN CLI Lua implementation (un.lua)
-- Tests extension detection, API calls, and end-to-end functionality
-- Try to load optional dependencies
local has_https, https = pcall(require, "ssl.https")
local has_ltn12, ltn12 = pcall(require, "ltn12")
local has_json, json = pcall(require, "cjson")
-- Test configuration
local script_dir = arg[0]:match("(.*/)")
local UN_SCRIPT = script_dir .. "../un.lua"
local FIB_PY = script_dir .. "../../test/fib.py"
-- TestResults class
local TestResults = {}
TestResults.__index = TestResults
function TestResults:new()
local obj = {
passed = 0,
failed = 0,
skipped = 0
}
setmetatable(obj, TestResults)
return obj
end
function TestResults:passTest(name)
print("PASS: " .. name)
self.passed = self.passed + 1
end
function TestResults:failTest(name, error)
print("FAIL: " .. name .. " - " .. error)
self.failed = self.failed + 1
end
function TestResults:skipTest(name, reason)
print("SKIP: " .. name .. " - " .. reason)
self.skipped = self.skipped + 1
end
local results = TestResults:new()
-- Extension map for testing
local EXTENSION_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",
[".java"] = "java", [".kt"] = "kotlin", [".cs"] = "csharp", [".hs"] = "haskell",
[".ml"] = "ocaml", [".clj"] = "clojure", [".ex"] = "elixir", [".erl"] = "erlang",
[".swift"] = "swift", [".r"] = "r", [".jl"] = "julia", [".dart"] = "dart",
[".scala"] = "scala", [".groovy"] = "groovy", [".nim"] = "nim", [".cr"] = "crystal",
[".v"] = "vlang", [".zig"] = "zig", [".fs"] = "fsharp", [".vb"] = "vb",
[".pas"] = "pascal", [".f90"] = "fortran", [".asm"] = "assembly", [".d"] = "d",
[".rkt"] = "racket", [".scm"] = "scheme", [".lisp"] = "common_lisp",
[".sol"] = "solidity", [".cob"] = "cobol", [".ada"] = "ada", [".tcl"] = "tcl",
}
local function detect_language(filename)
local ext = filename:match("%.([^.]+)$")
if ext then
return EXTENSION_MAP["." .. ext:lower()]
end
return nil
end
-- Test 1: Extension detection for Python
local status, err = pcall(function()
local lang = detect_language('test.py')
if lang == 'python' then
results:passTest('Extension detection: .py -> python')
else
results:failTest('Extension detection: .py -> python', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .py -> python', err)
end
-- Test 2: Extension detection for JavaScript
status, err = pcall(function()
local lang = detect_language('test.js')
if lang == 'javascript' then
results:passTest('Extension detection: .js -> javascript')
else
results:failTest('Extension detection: .js -> javascript', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .js -> javascript', err)
end
-- Test 3: Extension detection for Ruby
status, err = pcall(function()
local lang = detect_language('test.rb')
if lang == 'ruby' then
results:passTest('Extension detection: .rb -> ruby')
else
results:failTest('Extension detection: .rb -> ruby', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .rb -> ruby', err)
end
-- Test 4: Extension detection for Go
status, err = pcall(function()
local lang = detect_language('test.go')
if lang == 'go' then
results:passTest('Extension detection: .go -> go')
else
results:failTest('Extension detection: .go -> go', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .go -> go', err)
end
-- Test 5: Extension detection for Rust
status, err = pcall(function()
local lang = detect_language('test.rs')
if lang == 'rust' then
results:passTest('Extension detection: .rs -> rust')
else
results:failTest('Extension detection: .rs -> rust', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .rs -> rust', err)
end
-- Test 6: Extension detection for unknown extension
status, err = pcall(function()
local lang = detect_language('test.unknown')
if lang == nil then
results:passTest('Extension detection: .unknown -> nil')
else
results:failTest('Extension detection: .unknown -> nil', "Got " .. tostring(lang))
end
end)
if not status then
results:failTest('Extension detection: .unknown -> nil', err)
end
-- Test 7: API call test (requires UNSANDBOX_API_KEY)
if not os.getenv("UNSANDBOX_API_KEY") then
results:skipTest('API call test', 'UNSANDBOX_API_KEY not set')
elseif not (has_https and has_ltn12 and has_json) then
results:skipTest('API call test', 'Required Lua libraries not available (luasocket, luasec, lua-cjson)')
else
status, err = pcall(function()
local payload = json.encode({
language = 'python',
code = 'print("Hello from API")'
})
local response_body = {}
local res, code, headers, status_text = https.request{
url = "https://api.unsandbox.com/execute",
method = "POST",
headers = {
["Authorization"] = "Bearer " .. os.getenv("UNSANDBOX_API_KEY"),
["Content-Type"] = "application/json",
["Content-Length"] = tostring(#payload)
},
source = ltn12.source.string(payload),
sink = ltn12.sink.table(response_body)
}
if code == 200 then
local result = json.decode(table.concat(response_body))
if result.stdout and result.stdout:find('Hello from API') then
results:passTest('API call test')
else
results:failTest('API call test', "Unexpected result: " .. json.encode(result))
end
else
results:failTest('API call test', "HTTP " .. code .. ": " .. table.concat(response_body))
end
end)
if not status then
results:failTest('API call test', err)
end
end
-- Test 8: End-to-end test with fib.py
if not os.getenv("UNSANDBOX_API_KEY") then
results:skipTest('End-to-end fib.py test', 'UNSANDBOX_API_KEY not set')
else
-- Check if fib.py exists
local file = io.open(FIB_PY, "r")
if not file then
results:skipTest('End-to-end fib.py test', 'fib.py not found at ' .. FIB_PY)
else
file:close()
status, err = pcall(function()
local handle = io.popen(UN_SCRIPT .. ' ' .. FIB_PY .. ' 2>&1')
local output = handle:read("*a")
handle:close()
if output:find('fib%(10%) = 55') then
results:passTest('End-to-end fib.py test')
else
results:failTest('End-to-end fib.py test',
"Expected 'fib(10) = 55' in output, got: " .. output:sub(1, 200))
end
end)
if not status then
results:failTest('End-to-end fib.py test', err)
end
end
end
-- Print summary
print("\n" .. string.rep("=", 50))
print("Test Summary:")
print(" PASSED: " .. results.passed)
print(" FAILED: " .. results.failed)
print(" SKIPPED: " .. results.skipped)
print(" TOTAL: " .. (results.passed + results.failed + results.skipped))
print(string.rep("=", 50))
-- Exit with appropriate code
os.exit(results.failed == 0 and 0 or 1)