un-inception/tests/test_un_cr.cr
Russell Ballestrini a46bf88a3e Fix V result redefinition and Crystal nil type error
- V: Rename result variables in cmd_key to avoid redefinition (xdg_result, mac_result, win_result)
- Crystal: Fix Bool | Nil type by explicitly checking stdout.nil? before string check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:04:06 -05:00

175 lines
5.3 KiB
Crystal
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env crystal
# Comprehensive tests for un.cr (Crystal UN CLI Inception implementation)
# Compile and run with: crystal test_un_cr.cr
require "http/client"
require "json"
# Color codes
GREEN = "\033[32m"
RED = "\033[31m"
BLUE = "\033[34m"
RESET = "\033[0m"
# Test counters - use class with class variables
class TestCounter
@@passed = 0
@@failed = 0
def self.passed
@@passed
end
def self.failed
@@failed
end
def self.inc_passed
@@passed += 1
end
def self.inc_failed
@@failed += 1
end
end
# Extension to language mapping (from un.cr)
EXT_MAP = {
".jl" => "julia",
".r" => "r",
".cr" => "crystal",
".f90" => "fortran",
".cob" => "cobol",
".pro" => "prolog",
".forth" => "forth",
".4th" => "forth",
".py" => "python",
".js" => "javascript",
".rb" => "ruby",
".go" => "go",
".rs" => "rust",
".c" => "c",
".cpp" => "cpp",
".java" => "java",
".sh" => "bash"
}
def detect_language(filename : String) : String
ext = File.extname(filename).downcase
EXT_MAP.fetch(ext, "unknown")
end
def print_test(name : String, result : Bool)
if result
puts "#{GREEN}✓ PASS#{RESET}: #{name}"
TestCounter.inc_passed
else
puts "#{RED}✗ FAIL#{RESET}: #{name}"
TestCounter.inc_failed
end
end
puts "\n#{BLUE}========================================#{RESET}"
puts "#{BLUE}UN CLI Inception Tests - Crystal#{RESET}"
puts "#{BLUE}========================================#{RESET}\n"
# Test 1: Extension detection tests
puts "#{BLUE}Test Suite 1: Extension Detection#{RESET}"
print_test("Detect .jl as julia", detect_language("test.jl") == "julia")
print_test("Detect .r as r", detect_language("test.r") == "r")
print_test("Detect .cr as crystal", detect_language("test.cr") == "crystal")
print_test("Detect .f90 as fortran", detect_language("test.f90") == "fortran")
print_test("Detect .cob as cobol", detect_language("test.cob") == "cobol")
print_test("Detect .pro as prolog", detect_language("test.pro") == "prolog")
print_test("Detect .forth as forth", detect_language("test.forth") == "forth")
print_test("Detect .4th as forth", detect_language("test.4th") == "forth")
print_test("Detect .py as python", detect_language("test.py") == "python")
print_test("Detect .rs as rust", detect_language("test.rs") == "rust")
print_test("Detect unknown extension", detect_language("test.xyz") == "unknown")
# Test 2: API Integration Test
puts "\n#{BLUE}Test Suite 2: API Integration#{RESET}"
api_key = ENV["UNSANDBOX_API_KEY"]?
if api_key.nil? || api_key.empty?
puts "#{BLUE} SKIP#{RESET}: API integration test (UNSANDBOX_API_KEY not set)"
else
begin
url = URI.parse("https://api.unsandbox.com/execute")
headers = HTTP::Headers{
"Content-Type" => "application/json",
"Authorization" => "Bearer #{api_key}"
}
body = {
language: "python",
code: "print('Hello from test')"
}.to_json
response = HTTP::Client.post(url, headers: headers, body: body)
result = JSON.parse(response.body)
stdout = result["stdout"]?
api_works = !stdout.nil? && stdout.as_s.includes?("Hello from test")
print_test("API endpoint reachable and functional", api_works)
rescue ex
print_test("API endpoint reachable and functional", false)
puts " Error: #{ex.message}"
end
end
# Test 3: End-to-end functional test
puts "\n#{BLUE}Test Suite 3: End-to-End Functional Test#{RESET}"
if api_key.nil? || api_key.empty?
puts "#{BLUE} SKIP#{RESET}: E2E test (UNSANDBOX_API_KEY not set)"
else
fib_file = "../../test/fib.cr"
fib_file = "/home/fox/git/unsandbox.com/cli/test/fib.cr" unless File.exists?(fib_file)
if File.exists?(fib_file)
begin
un_script = "../un.cr"
un_script = "/home/fox/git/unsandbox.com/cli/inception/un.cr" unless File.exists?(un_script)
output = IO::Memory.new
error = IO::Memory.new
process = Process.run("crystal", args: ["run", un_script, fib_file],
output: output, error: error)
result = output.to_s + error.to_s
has_fib10 = result.includes?("fib(10) = 55")
has_fib5 = result.includes?("fib(5) = 5")
has_fib0 = result.includes?("fib(0) = 0")
print_test("E2E: fib.cr produces fib(10) = 55", has_fib10)
print_test("E2E: fib.cr produces fib(5) = 5", has_fib5)
print_test("E2E: fib.cr produces fib(0) = 0", has_fib0)
rescue ex
print_test("E2E: fib.cr execution", false)
puts " Error: #{ex.message}"
end
else
puts "#{BLUE} SKIP#{RESET}: E2E test (fib.cr not found at expected location)"
end
end
# Test 4: Error handling tests
puts "\n#{BLUE}Test Suite 4: Error Handling#{RESET}"
print_test("Unknown extension returns 'unknown'", detect_language("file.unknown") == "unknown")
print_test("Case insensitive detection", detect_language("TEST.CR") == "crystal")
print_test("Multiple dots in filename", detect_language("my.test.py") == "python")
# Print summary
puts "\n#{BLUE}========================================#{RESET}"
puts "#{BLUE}Test Summary#{RESET}"
puts "#{BLUE}========================================#{RESET}"
puts "#{GREEN}Passed: #{TestCounter.passed}#{RESET}"
puts "#{RED}Failed: #{TestCounter.failed}#{RESET}"
puts "#{BLUE}Total: #{TestCounter.passed + TestCounter.failed}#{RESET}"
if TestCounter.failed > 0
puts "\n#{RED}TESTS FAILED#{RESET}"
exit 1
else
puts "\n#{GREEN}ALL TESTS PASSED#{RESET}"
exit 0
end