added new unit tests

This commit is contained in:
2026-03-23 21:52:56 -07:00
parent 869368af56
commit ffd7ac15f6
7 changed files with 1107 additions and 1500 deletions
+10 -5
View File
@@ -1421,8 +1421,10 @@ function multi:newProcessor(name, opts, priority)
function c:Destroy()
Active = false
if c.process then
c.process:Destroy()
end
end
function c:setTaskDelay(delay)
if type(delay) == "function" then
@@ -2648,7 +2650,7 @@ end
function multi.Round(num, numDecimalPlaces)
local mult = 10 ^ (numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
return math.floor((num * mult) + 0.5 + 1e-10) / mult
end
function multi.AlignTable(tab)
@@ -2697,6 +2699,12 @@ end
function multi:reallocate(processor, index)
index=index or #processor.Mainloop+1
local int=self.Parent
for i = #int.Mainloop, 1, -1 do
if int.Mainloop[i] == self then
table.remove(int.Mainloop,i)
break
end
end
self.Parent=processor
if index then
table.insert(processor.Mainloop, index, self)
@@ -2794,11 +2802,8 @@ local function random_hex(len)
end
return result
end
multi.generate_uuid7 = function()
-- Seed random number generator with current time
math.randomseed(os.time())
multi.generate_uuid7 = function()
-- Get timestamp in milliseconds
local timestamp_ms = get_timestamp_ms()
-39
View File
@@ -1,39 +0,0 @@
function love.conf(t)
t.identity = nil -- The name of the save directory (string)
t.version = "12.0" -- The LOVE version this game was made for (string)
t.console = true -- Attach a console (boolean, Windows only)
t.window.title = "MultiThreadTest" -- The window title (string)
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
t.window.width = 1280 -- The window width (number)
t.window.height = 720 -- The window height (number)
t.window.borderless = false -- Remove all border visuals from the window (boolean)
t.window.resizable = true -- Let the window be user-resizable (boolean)
t.window.minwidth = 1 -- Minimum window width if the window is resizable (number)
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
t.window.fullscreen = false -- Enable fullscreen (boolean)
t.window.fullscreentype = "desktop" -- Standard fullscreen or desktop fullscreen mode (string)
t.window.vsync = false -- Enable vertical sync (boolean)
t.window.fsaa = 2 -- The number of samples to use with multi-sampled antialiasing (number)
t.window.display = 1 -- Index of the monitor to show the window in (number)
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
t.window.srgb = false -- Enable sRGB gamma correction when drawing to the screen (boolean)
t.window.x = nil -- The x-coordinate of the window's position in the specified display (number)
t.window.y = nil -- The y-coordinate of the window's position in the specified display (number)
t.modules.audio = false -- Enable the audio module (boolean)
t.modules.event = false -- Enable the event module (boolean)
t.modules.graphics = false -- Enable the graphics module (boolean)
t.modules.image = false -- Enable the image module (boolean)
t.modules.joystick = false -- Enable the joystick module (boolean)
t.modules.keyboard = false -- Enable the keyboard module (boolean)
t.modules.math = false -- Enable the math module (boolean)
t.modules.mouse = false -- Enable the mouse module (boolean)
t.modules.physics = false -- Enable the physics module (boolean)
t.modules.sound = false -- Enable the sound module (boolean)
t.modules.system = false -- Enable the system module (boolean)
t.modules.timer = false -- Enable the timer module (boolean)
t.modules.window = false -- Enable the window module (boolean)
t.modules.thread = true -- Enable the thread module (boolean)
end
-10
View File
@@ -1,10 +0,0 @@
package.path = "../?/init.lua;../?.lua;"..package.path
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
require("lldebugger").start()
end
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
require("runtests")
require("threadtests")
+1095
View File
File diff suppressed because it is too large Load Diff
-271
View File
@@ -1,271 +0,0 @@
package.path = "../?/init.lua;../?.lua;./init.lua;./?.lua;" .. package.path
local multi, thread = require("multi"):init{print=true,warn=true,error=true}--{priority=true}
local good = false
local proc = multi:newProcessor("Test")
local testing = {}
function testing.False(value)
if value ~= false then
thread.kill("Expected value to be false")
end
end
function testing.True(value)
if value ~= true then
thread.kill("Expected value to be true")
end
end
function testing.IsNil(value)
if value ~= nil then
thread.kill("Expected nil, but got: " .. tostring(value) .."")
end
end
function testing.NotNil(value)
if value == nil then
thread.kill("Expected value not to be nil.")
end
end
function testing.Equal(expected, actual)
if expected ~= actual then
thread.kill("Not equal: \n" ..
"expected: " .. tostring(expected) .. "\n" ..
"actual : " .. tostring(actual) .. "\n")
end
end
function testing.NotEqual(expected, actual)
if expected == actual then
thread.kill("Should not be: values are equal")
end
end
function getOS()
-- ask LuaJIT first
if jit then
return jit.os
end
-- Unix, Linux variants
local fh,err = assert(io.popen("uname -o 2>/dev/null","r"))
if fh then
osname = fh:read()
end
return osname or "Windows"
end
function ListFiles(path)
files = {}
if getOS() == "Windows" then
for dir in io.popen([[dir /A-d "]] .. path .. [[" /b]]):lines() do table.insert(files,dir) end
else
for dir in io.popen([[ls -pa "]] .. path .. [[" | grep -v /]]):lines() do table.insert(files,dir) end
end
return files
end
print("Version: "..multi.Version)
proc.Start()
proc:newAlarm(3):OnRing(function()
good = true
end)
runTest = thread:newFunction(function()
-- local alarms,tsteps,steps,loops,tloops,updaters,events=false,0,0,0,0,0,false
-- multi.print("Testing Basic Features. If this fails most other features will probably not work!")
-- proc:newAlarm(2):OnRing(function(a)
-- alarms = true
-- a:Destroy()
-- end)
-- proc:newTStep(1,10,1,.1):OnStep(function(t)
-- tsteps = tsteps + 1
-- end):OnEnd(function(step)
-- step:Destroy()
-- end)
-- proc:newStep(1,10):OnStep(function(s)
-- steps = steps + 1
-- end):OnEnd(function(step)
-- step:Destroy()
-- end)
-- local loop = proc:newLoop(function(l)
-- loops = loops + 1
-- end)
-- proc:newTLoop(function(t)
-- tloops = tloops + 1
-- end,.1)
-- local updater = proc:newUpdater(1):OnUpdate(function()
-- updaters = updaters + 1
-- end)
-- local event = proc:newEvent(function()
-- return alarms
-- end)
-- event.OnEvent(function(evnt)
-- evnt:Destroy()
-- events = true
-- multi.success("Alarms: Ok")
-- multi.success("Events: Ok")
-- if tsteps == 10 then multi.success("TSteps: Ok") else multi.error("TSteps: Bad!") end
-- if steps == 10 then multi.success("Steps: Ok") else multi.error("Steps: Bad!") end
-- if loops > 100 then multi.success("Loops: Ok") else multi.error("Loops: Bad!") end
-- if tloops > 10 then multi.success("TLoops: Ok") else multi.error("TLoops: Bad!") end
-- if updaters > 100 then multi.success("Updaters: Ok") else multi.error("Updaters: Bad!") end
-- end)
-- thread.hold(event.OnEvent)
-- multi.print("Starting Connection and Thread tests!")
-- func = thread:newFunction(function(count)
-- multi.print("Starting Status test: ",count)
-- local a = 0
-- while true do
-- a = a + 1
-- thread.sleep(.1)
-- thread.pushStatus(a,count)
-- if a == count then break end
-- end
-- return "Done", true, math.random(1,10000)
-- end)
-- local ret = func(10)
-- local ret2 = func(15)
-- local ret3 = func(20)
-- local s1,s2,s3 = 0,0,0
-- ret.OnError(function(...)
-- multi.error("Func 1:",...)
-- end)
-- ret2.OnError(function(...)
-- multi.error("Func 2:",...)
-- end)
-- ret3.OnError(function(...)
-- multi.error("Func 3:",...)
-- end)
-- ret.OnStatus(function(part,whole)
-- s1 = math.ceil((part/whole)*1000)/10
-- end)
-- ret2.OnStatus(function(part,whole)
-- s2 = math.ceil((part/whole)*1000)/10
-- end)
-- ret3.OnStatus(function(part,whole)
-- s3 = math.ceil((part/whole)*1000)/10
-- end)
-- ret.OnReturn(function(...)
-- multi.success("Done 1",...)
-- end)
-- ret2.OnReturn(function(...)
-- multi.success("Done 2",...)
-- end)
-- ret3.OnReturn(function(...)
-- multi.success("Done 3",...)
-- end)
-- local err, timeout = thread.hold(ret.OnReturn * ret2.OnReturn * ret3.OnReturn)
-- if s1 == 100 and s2 == 100 and s3 == 100 then
-- multi.success("Threads: All tests Ok")
-- else
-- if s1>0 and s2>0 and s3 > 0 then
-- multi.success("Thread OnStatus: Ok")
-- else
-- multi.error("Threads OnStatus or thread.hold(conn) Error!")
-- end
-- if timeout then
-- multi.error("Connection Error!")
-- else
-- multi.success("Connection Test 1: Ok")
-- end
-- multi.error("Connection holding Error!")
-- end
-- conn1 = proc:newConnection()
-- conn2 = proc:newConnection()
-- conn3 = proc:newConnection()
-- local c1,c2,c3,c4 = false,false,false,false
-- local a = conn1(function()
-- c1 = true
-- end)
-- local b = conn2(function()
-- c2 = true
-- end)
-- local c = conn3(function()
-- c3 = true
-- end)
-- local d = conn3(function()
-- c4 = true
-- end)
-- conn1:Fire()
-- conn2:Fire()
-- conn3:Fire()
-- if c1 and c2 and c3 and c4 then
-- multi.success("Connection Test 2: Ok")
-- else
-- multi.error("Connection Test 2: Error")
-- end
-- c3 = false
-- c4 = false
-- conn3:Unconnect(d)
-- conn3:Fire()
-- if c3 and not(c4) then
-- multi.success("Connection Test 3: Ok")
-- else
-- multi.error("Connection Test 3: Error removing connection")
-- end
units = ListFiles("tests/units")
for _, file in pairs(units) do
multi.print("Running tests in: " .. file)
unit = loadfile("tests/units/" .. file)()
function Test(...)
unit.Test(...)
multi.success(file)
end
func = thread:newFunction(Test, true)
func(multi:newProcessor(file), thread, testing)
end
if not love then
local ec = 0
multi.print("Testing pseudo threading")
capture = io.popen("lua tests/threadtests.lua p"):read("*a")
if capture:lower():match("error") then
ec = ec + 1
os.exit(1)
else
io.write(capture)
end
multi.print("Testing lanes threading")
capture = io.popen("lua tests/threadtests.lua l"):read("*a")
if capture:lower():match("error") then
ec = ec + 1
os.exit(1)
else
io.write(capture)
end
os.exit(0)
end
end)
local handle = runTest()
handle.OnError(function(...)
multi.error("Something went wrong with the test!")
print(...)
end)
if not love then
multi:mainloop()
else
local hold = thread:newFunction(function()
thread.hold(handle.OnError + handle.OnReturn)
end, true)
hold()
multi.print("Starting Threading tests!")
end
-71
View File
@@ -1,71 +0,0 @@
function Test(multi, thread, t)
multi.print("Testing Connection operators")
do
multi.print("Testing: conn1 + conn2")
local conn1 = multi:newConnection()
local conn2 = multi:newConnection()
local conn3 = conn1 + conn2
local count = 0
conn3(function()
count = count + 1
end)
conn1:Fire()
t.Equal(1, count)
conn2:Fire()
t.Equal(2, count)
end
do
multi.print("Testing: conn1 * conn2")
local conn1 = multi:newConnection()
local conn2 = multi:newConnection()
local conn3 = conn1 * conn2
local count = 0
conn3(function()
count = count + 1
end)
conn1:Fire()
t.Equal(0, count)
conn2:Fire()
t.Equal(1, count)
end
do
multi.print("Testing: conn .. function")
local called = false
local conn1 = multi:newConnection()
local conn2 = conn1 .. function() called = true end
conn1(function()
t.False(called)
end)
conn2:Fire()
t.True(called)
end
do
multi.print("function .. conn")
local status = false
local conn1 = multi:newConnection()
local conn2 = function(test) return test end .. conn1
conn1(function()
status = true
end)
conn2:Fire(false)
t.False(status)
conn2:Fire(true)
t.True(status)
end
end
return {
Test = Test
}
File diff suppressed because it is too large Load Diff