mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-14 22:17:35 +00:00
Feat: Add Support for Zig, Nix, Lua (#498)
Extensive tests for each of the three languages were added
This commit is contained in:
1 parent
47ccc916a4
commit
7e6dbdc9ba
30 files changed
+3094
-4
No files matched your search
@@ -0,0 +1,13 @@
|
||||
# Lua specific
|
||||
*.luac
|
||||
.luarocks/
|
||||
lua_modules/
|
||||
luarocks/
|
||||
|
||||
# Build artifacts
|
||||
build/
|
||||
dist/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
-- main.lua: Entry point for the test application
|
||||
|
||||
local calculator = require("src.calculator")
|
||||
local utils = require("src.utils")
|
||||
|
||||
local function print_banner()
|
||||
print("=" .. string.rep("=", 40))
|
||||
print(" Lua Test Repository")
|
||||
print("=" .. string.rep("=", 40))
|
||||
end
|
||||
|
||||
local function test_calculator()
|
||||
print("\nTesting Calculator Module:")
|
||||
print("5 + 3 =", calculator.add(5, 3))
|
||||
print("10 - 4 =", calculator.subtract(10, 4))
|
||||
print("6 * 7 =", calculator.multiply(6, 7))
|
||||
print("15 / 3 =", calculator.divide(15, 3))
|
||||
print("2^8 =", calculator.power(2, 8))
|
||||
print("5! =", calculator.factorial(5))
|
||||
|
||||
local numbers = {5, 2, 8, 3, 9, 1, 7}
|
||||
print("Mean of", table.concat(numbers, ", "), "=", calculator.mean(numbers))
|
||||
print("Median of", table.concat(numbers, ", "), "=", calculator.median(numbers))
|
||||
end
|
||||
|
||||
local function test_utils()
|
||||
print("\nTesting Utils Module:")
|
||||
|
||||
-- String utilities
|
||||
print("Trimmed ' hello ' =", "'" .. utils.trim(" hello ") .. "'")
|
||||
local parts = utils.split("apple,banana,orange", ",")
|
||||
print("Split 'apple,banana,orange' by ',' =", table.concat(parts, " | "))
|
||||
print("'hello' starts with 'he' =", utils.starts_with("hello", "he"))
|
||||
print("'world' ends with 'ld' =", utils.ends_with("world", "ld"))
|
||||
|
||||
-- Table utilities
|
||||
local t1 = {a = 1, b = 2}
|
||||
local t2 = {b = 3, c = 4}
|
||||
local merged = utils.table_merge(t1, t2)
|
||||
print("Merged tables: a=" .. (merged.a or "nil") ..
|
||||
", b=" .. (merged.b or "nil") ..
|
||||
", c=" .. (merged.c or "nil"))
|
||||
|
||||
-- Logger
|
||||
local logger = utils.Logger:new("TestApp")
|
||||
logger:info("Application started")
|
||||
logger:debug("Debug information")
|
||||
logger:warn("This is a warning")
|
||||
end
|
||||
|
||||
local function interactive_calculator()
|
||||
print("\nInteractive Calculator (type 'quit' to exit):")
|
||||
while true do
|
||||
io.write("Enter operation (e.g., '5 + 3'): ")
|
||||
local input = io.read()
|
||||
|
||||
if input == "quit" then
|
||||
break
|
||||
end
|
||||
|
||||
-- Simple parser for basic operations
|
||||
local a, op, b = input:match("(%d+)%s*([%+%-%*/])%s*(%d+)")
|
||||
if a and op and b then
|
||||
a = tonumber(a)
|
||||
b = tonumber(b)
|
||||
local result
|
||||
|
||||
if op == "+" then
|
||||
result = calculator.add(a, b)
|
||||
elseif op == "-" then
|
||||
result = calculator.subtract(a, b)
|
||||
elseif op == "*" then
|
||||
result = calculator.multiply(a, b)
|
||||
elseif op == "/" then
|
||||
local success, res = pcall(calculator.divide, a, b)
|
||||
if success then
|
||||
result = res
|
||||
else
|
||||
print("Error: " .. res)
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
|
||||
print("Result: " .. result)
|
||||
else
|
||||
print("Invalid input. Please use format: number operator number")
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
-- Main execution
|
||||
local function main(args)
|
||||
print_banner()
|
||||
|
||||
if #args == 0 then
|
||||
test_calculator()
|
||||
test_utils()
|
||||
elseif args[1] == "interactive" then
|
||||
interactive_calculator()
|
||||
elseif args[1] == "test" then
|
||||
test_calculator()
|
||||
test_utils()
|
||||
print("\nAll tests completed!")
|
||||
else
|
||||
print("Usage: lua main.lua [interactive|test]")
|
||||
end
|
||||
end
|
||||
|
||||
-- Run main function
|
||||
main(arg or {})
|
||||
@@ -0,0 +1,76 @@
|
||||
-- calculator.lua: A simple calculator module for testing LSP features
|
||||
|
||||
local calculator = {}
|
||||
|
||||
-- Basic arithmetic operations
|
||||
function calculator.add(a, b)
|
||||
return a + b
|
||||
end
|
||||
|
||||
function calculator.subtract(a, b)
|
||||
return a - b
|
||||
end
|
||||
|
||||
function calculator.multiply(a, b)
|
||||
return a * b
|
||||
end
|
||||
|
||||
function calculator.divide(a, b)
|
||||
if b == 0 then
|
||||
error("Division by zero")
|
||||
end
|
||||
return a / b
|
||||
end
|
||||
|
||||
-- Advanced operations
|
||||
function calculator.power(base, exponent)
|
||||
return base ^ exponent
|
||||
end
|
||||
|
||||
function calculator.factorial(n)
|
||||
if n < 0 then
|
||||
error("Factorial is not defined for negative numbers")
|
||||
elseif n == 0 or n == 1 then
|
||||
return 1
|
||||
else
|
||||
local result = 1
|
||||
for i = 2, n do
|
||||
result = result * i
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
-- Statistics functions
|
||||
function calculator.mean(numbers)
|
||||
if #numbers == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local sum = 0
|
||||
for _, num in ipairs(numbers) do
|
||||
sum = sum + num
|
||||
end
|
||||
return sum / #numbers
|
||||
end
|
||||
|
||||
function calculator.median(numbers)
|
||||
if #numbers == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local sorted = {}
|
||||
for i, v in ipairs(numbers) do
|
||||
sorted[i] = v
|
||||
end
|
||||
table.sort(sorted)
|
||||
|
||||
local mid = math.floor(#sorted / 2)
|
||||
if #sorted % 2 == 0 then
|
||||
return (sorted[mid] + sorted[mid + 1]) / 2
|
||||
else
|
||||
return sorted[mid + 1]
|
||||
end
|
||||
end
|
||||
|
||||
return calculator
|
||||
@@ -0,0 +1,120 @@
|
||||
-- utils.lua: Utility functions for the test repository
|
||||
|
||||
local utils = {}
|
||||
|
||||
-- String utilities
|
||||
function utils.trim(s)
|
||||
return s:match("^%s*(.-)%s*$")
|
||||
end
|
||||
|
||||
function utils.split(str, delimiter)
|
||||
local result = {}
|
||||
local pattern = string.format("([^%s]+)", delimiter)
|
||||
for match in string.gmatch(str, pattern) do
|
||||
table.insert(result, match)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function utils.starts_with(str, prefix)
|
||||
return str:sub(1, #prefix) == prefix
|
||||
end
|
||||
|
||||
function utils.ends_with(str, suffix)
|
||||
return str:sub(-#suffix) == suffix
|
||||
end
|
||||
|
||||
-- Table utilities
|
||||
function utils.deep_copy(orig)
|
||||
local orig_type = type(orig)
|
||||
local copy
|
||||
if orig_type == 'table' then
|
||||
copy = {}
|
||||
for orig_key, orig_value in next, orig, nil do
|
||||
copy[utils.deep_copy(orig_key)] = utils.deep_copy(orig_value)
|
||||
end
|
||||
setmetatable(copy, utils.deep_copy(getmetatable(orig)))
|
||||
else
|
||||
copy = orig
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
function utils.table_contains(tbl, value)
|
||||
for _, v in ipairs(tbl) do
|
||||
if v == value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function utils.table_merge(t1, t2)
|
||||
local result = {}
|
||||
for k, v in pairs(t1) do
|
||||
result[k] = v
|
||||
end
|
||||
for k, v in pairs(t2) do
|
||||
result[k] = v
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- File utilities
|
||||
function utils.read_file(path)
|
||||
local file = io.open(path, "r")
|
||||
if not file then
|
||||
return nil, "Could not open file: " .. path
|
||||
end
|
||||
local content = file:read("*all")
|
||||
file:close()
|
||||
return content
|
||||
end
|
||||
|
||||
function utils.write_file(path, content)
|
||||
local file = io.open(path, "w")
|
||||
if not file then
|
||||
return false, "Could not open file for writing: " .. path
|
||||
end
|
||||
file:write(content)
|
||||
file:close()
|
||||
return true
|
||||
end
|
||||
|
||||
-- Class-like structure
|
||||
utils.Logger = {}
|
||||
utils.Logger.__index = utils.Logger
|
||||
|
||||
function utils.Logger:new(name)
|
||||
local self = setmetatable({}, utils.Logger)
|
||||
self.name = name or "default"
|
||||
self.level = "info"
|
||||
return self
|
||||
end
|
||||
|
||||
function utils.Logger:set_level(level)
|
||||
self.level = level
|
||||
end
|
||||
|
||||
function utils.Logger:log(message, level)
|
||||
level = level or self.level
|
||||
print(string.format("[%s] %s: %s", self.name, level:upper(), message))
|
||||
end
|
||||
|
||||
function utils.Logger:debug(message)
|
||||
self:log(message, "debug")
|
||||
end
|
||||
|
||||
function utils.Logger:info(message)
|
||||
self:log(message, "info")
|
||||
end
|
||||
|
||||
function utils.Logger:warn(message)
|
||||
self:log(message, "warn")
|
||||
end
|
||||
|
||||
function utils.Logger:error(message)
|
||||
self:log(message, "error")
|
||||
end
|
||||
|
||||
return utils
|
||||
@@ -0,0 +1,93 @@
|
||||
-- test_calculator.lua: Unit tests for calculator module
|
||||
|
||||
local calculator = require("src.calculator")
|
||||
|
||||
local function assert_equals(actual, expected, message)
|
||||
if actual ~= expected then
|
||||
error(string.format("%s: expected %s, got %s",
|
||||
message or "Assertion failed", tostring(expected), tostring(actual)))
|
||||
end
|
||||
end
|
||||
|
||||
local function assert_error(func, message)
|
||||
local success = pcall(func)
|
||||
if success then
|
||||
error(string.format("%s: expected error but none was thrown",
|
||||
message or "Assertion failed"))
|
||||
end
|
||||
end
|
||||
|
||||
local function test_basic_operations()
|
||||
print("Testing basic operations...")
|
||||
assert_equals(calculator.add(2, 3), 5, "Addition test")
|
||||
assert_equals(calculator.add(-5, 5), 0, "Addition with negative")
|
||||
assert_equals(calculator.add(0, 0), 0, "Addition with zeros")
|
||||
|
||||
assert_equals(calculator.subtract(10, 3), 7, "Subtraction test")
|
||||
assert_equals(calculator.subtract(5, 10), -5, "Subtraction negative result")
|
||||
|
||||
assert_equals(calculator.multiply(4, 5), 20, "Multiplication test")
|
||||
assert_equals(calculator.multiply(-3, 4), -12, "Multiplication with negative")
|
||||
assert_equals(calculator.multiply(0, 100), 0, "Multiplication with zero")
|
||||
|
||||
assert_equals(calculator.divide(10, 2), 5, "Division test")
|
||||
assert_equals(calculator.divide(7, 2), 3.5, "Division with decimal result")
|
||||
assert_error(function() calculator.divide(5, 0) end, "Division by zero")
|
||||
|
||||
print("✓ Basic operations tests passed")
|
||||
end
|
||||
|
||||
local function test_advanced_operations()
|
||||
print("Testing advanced operations...")
|
||||
assert_equals(calculator.power(2, 3), 8, "Power test")
|
||||
assert_equals(calculator.power(5, 0), 1, "Power of zero")
|
||||
assert_equals(calculator.power(10, -1), 0.1, "Negative exponent")
|
||||
|
||||
assert_equals(calculator.factorial(0), 1, "Factorial of 0")
|
||||
assert_equals(calculator.factorial(1), 1, "Factorial of 1")
|
||||
assert_equals(calculator.factorial(5), 120, "Factorial of 5")
|
||||
assert_equals(calculator.factorial(10), 3628800, "Factorial of 10")
|
||||
assert_error(function() calculator.factorial(-1) end, "Factorial of negative")
|
||||
|
||||
print("✓ Advanced operations tests passed")
|
||||
end
|
||||
|
||||
local function test_statistics()
|
||||
print("Testing statistics functions...")
|
||||
|
||||
-- Mean tests
|
||||
assert_equals(calculator.mean({1, 2, 3, 4, 5}), 3, "Mean of sequential numbers")
|
||||
assert_equals(calculator.mean({10}), 10, "Mean of single number")
|
||||
assert_equals(calculator.mean({-5, 5}), 0, "Mean with negatives")
|
||||
assert_equals(calculator.mean({}), nil, "Mean of empty array")
|
||||
|
||||
-- Median tests
|
||||
assert_equals(calculator.median({1, 2, 3, 4, 5}), 3, "Median of odd count")
|
||||
assert_equals(calculator.median({1, 2, 3, 4}), 2.5, "Median of even count")
|
||||
assert_equals(calculator.median({5, 1, 3, 2, 4}), 3, "Median of unsorted")
|
||||
assert_equals(calculator.median({7}), 7, "Median of single number")
|
||||
assert_equals(calculator.median({}), nil, "Median of empty array")
|
||||
|
||||
print("✓ Statistics tests passed")
|
||||
end
|
||||
|
||||
-- Run all tests
|
||||
local function run_all_tests()
|
||||
print("Running calculator tests...\n")
|
||||
test_basic_operations()
|
||||
test_advanced_operations()
|
||||
test_statistics()
|
||||
print("\n✅ All calculator tests passed!")
|
||||
end
|
||||
|
||||
-- Execute tests if run directly
|
||||
if arg and arg[0] and arg[0]:match("test_calculator%.lua$") then
|
||||
run_all_tests()
|
||||
end
|
||||
|
||||
return {
|
||||
run_all_tests = run_all_tests,
|
||||
test_basic_operations = test_basic_operations,
|
||||
test_advanced_operations = test_advanced_operations,
|
||||
test_statistics = test_statistics
|
||||
}
|
||||
Reference in new issue
Block a user