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.
163 lines
5 KiB
Haskell
Executable file
163 lines
5 KiB
Haskell
Executable file
#!/usr/bin/env runhaskell
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-
|
|
Haskell UN CLI Test Suite
|
|
|
|
Usage:
|
|
chmod +x test_un_hs.hs
|
|
./test_un_hs.hs
|
|
|
|
Or with runhaskell:
|
|
runhaskell test_un_hs.hs
|
|
|
|
Tests the Haskell UN CLI implementation (un.hs) for:
|
|
1. Extension detection logic
|
|
2. API integration (if UNSANDBOX_API_KEY is set)
|
|
3. End-to-end execution with fib.hs test file
|
|
-}
|
|
|
|
import System.FilePath (takeExtension)
|
|
import System.Environment (lookupEnv)
|
|
import System.Exit (exitWith, ExitCode(..))
|
|
import System.Process (readProcessWithExitCode)
|
|
import Control.Monad (unless, when)
|
|
import Data.List (isInfixOf)
|
|
|
|
-- ANSI color codes
|
|
green, red, yellow, reset :: String
|
|
green = "\x1b[32m"
|
|
red = "\x1b[31m"
|
|
yellow = "\x1b[33m"
|
|
reset = "\x1b[0m"
|
|
|
|
-- Extension to language mapping (from un.hs)
|
|
extToLang :: String -> Maybe String
|
|
extToLang ext = lookup ext extMap
|
|
where
|
|
extMap = [ (".hs", "haskell"), (".ml", "ocaml"), (".clj", "clojure")
|
|
, (".scm", "scheme"), (".lisp", "commonlisp"), (".erl", "erlang")
|
|
, (".ex", "elixir"), (".py", "python"), (".js", "javascript")
|
|
, (".rb", "ruby"), (".go", "go"), (".rs", "rust")
|
|
, (".c", "c"), (".cpp", "cpp"), (".java", "java")
|
|
]
|
|
|
|
-- Test result type
|
|
data TestResult = Pass | Fail String
|
|
|
|
-- Print test result
|
|
printResult :: String -> TestResult -> IO Bool
|
|
printResult testName result = case result of
|
|
Pass -> do
|
|
putStrLn $ green ++ "✓ PASS" ++ reset ++ " - " ++ testName
|
|
return True
|
|
Fail msg -> do
|
|
putStrLn $ red ++ "✗ FAIL" ++ reset ++ " - " ++ testName
|
|
putStrLn $ " Error: " ++ msg
|
|
return False
|
|
|
|
-- Test 1: Extension detection
|
|
testExtensionDetection :: IO TestResult
|
|
testExtensionDetection = do
|
|
let tests = [ (".hs", Just "haskell")
|
|
, (".ml", Just "ocaml")
|
|
, (".clj", Just "clojure")
|
|
, (".scm", Just "scheme")
|
|
, (".lisp", Just "commonlisp")
|
|
, (".erl", Just "erlang")
|
|
, (".ex", Just "elixir")
|
|
, (".py", Just "python")
|
|
, (".js", Just "javascript")
|
|
, (".rb", Just "ruby")
|
|
]
|
|
|
|
let failures = [ (ext, expected, actual)
|
|
| (ext, expected) <- tests
|
|
, let actual = extToLang ext
|
|
, actual /= expected
|
|
]
|
|
|
|
if null failures
|
|
then return Pass
|
|
else return $ Fail $ "Extension mappings failed: " ++ show failures
|
|
|
|
-- Test 2: API integration (if API key is available)
|
|
testAPIIntegration :: IO TestResult
|
|
testAPIIntegration = do
|
|
apiKeyMaybe <- lookupEnv "UNSANDBOX_API_KEY"
|
|
case apiKeyMaybe of
|
|
Nothing -> return $ Pass -- Skip test if no API key
|
|
Just _ -> do
|
|
-- Create a simple test file
|
|
let testCode = "main = putStrLn \"test\"\n"
|
|
writeFile "/tmp/test_un_hs_api.hs" testCode
|
|
|
|
-- Run the CLI
|
|
(exitCode, stdout, stderr) <- readProcessWithExitCode
|
|
"./un.hs"
|
|
["/tmp/test_un_hs_api.hs"]
|
|
""
|
|
|
|
-- Check if it executed successfully
|
|
if exitCode == ExitSuccess && "test" `isInfixOf` stdout
|
|
then return Pass
|
|
else return $ Fail $ "API call failed: " ++ show exitCode ++
|
|
", stdout: " ++ stdout ++
|
|
", stderr: " ++ stderr
|
|
|
|
-- Test 3: Functional test with fib.hs
|
|
testFibonacci :: IO TestResult
|
|
testFibonacci = do
|
|
apiKeyMaybe <- lookupEnv "UNSANDBOX_API_KEY"
|
|
case apiKeyMaybe of
|
|
Nothing -> return Pass -- Skip test if no API key
|
|
Just _ -> do
|
|
-- Check if fib.hs exists
|
|
let fibPath = "../test/fib.hs"
|
|
|
|
-- Run the CLI with fib.hs
|
|
(exitCode, stdout, stderr) <- readProcessWithExitCode
|
|
"./un.hs"
|
|
[fibPath]
|
|
""
|
|
|
|
-- Check if output contains expected fibonacci result
|
|
if exitCode == ExitSuccess && "fib(10) = 55" `isInfixOf` stdout
|
|
then return Pass
|
|
else return $ Fail $ "Fibonacci test failed: " ++ show exitCode ++
|
|
", stdout: " ++ stdout ++
|
|
", stderr: " ++ stderr
|
|
|
|
-- Main test runner
|
|
main :: IO ()
|
|
main = do
|
|
putStrLn "=== Haskell UN CLI Test Suite ==="
|
|
putStrLn ""
|
|
|
|
-- Check if API key is set
|
|
apiKeyMaybe <- lookupEnv "UNSANDBOX_API_KEY"
|
|
when (apiKeyMaybe == Nothing) $ do
|
|
putStrLn $ yellow ++ "⚠ WARNING" ++ reset ++
|
|
" - UNSANDBOX_API_KEY not set, skipping API tests"
|
|
putStrLn ""
|
|
|
|
-- Run tests
|
|
results <- sequence
|
|
[ testExtensionDetection >>= printResult "Extension detection"
|
|
, testAPIIntegration >>= printResult "API integration"
|
|
, testFibonacci >>= printResult "Fibonacci end-to-end test"
|
|
]
|
|
|
|
putStrLn ""
|
|
|
|
-- Summary
|
|
let passed = length $ filter id results
|
|
let total = length results
|
|
|
|
if passed == total
|
|
then do
|
|
putStrLn $ green ++ "✓ All tests passed (" ++ show passed ++ "/" ++ show total ++ ")" ++ reset
|
|
exitWith ExitSuccess
|
|
else do
|
|
putStrLn $ red ++ "✗ Some tests failed (" ++ show passed ++ "/" ++ show total ++ " passed)" ++ reset
|
|
exitWith $ ExitFailure 1
|