542 lines
14 KiB
Lua
542 lines
14 KiB
Lua
package.path = package.path .. ";?.lua"
|
|
|
|
local luaunit = require("testing/luaunit")
|
|
require("testing/loveStub") -- Required to mock LOVE functions
|
|
local FlexLove = require("FlexLove")
|
|
local Gui, Color, enums = FlexLove.GUI, FlexLove.Color, FlexLove.enums
|
|
|
|
TestAuxiliaryFunctions = {}
|
|
|
|
function TestAuxiliaryFunctions:setUp()
|
|
-- Clear any existing GUI elements
|
|
Gui.destroy()
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:tearDown()
|
|
-- Clean up after each test
|
|
Gui.destroy()
|
|
end
|
|
|
|
-- ============================================
|
|
-- Color Utility Functions Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testColorNewBasic()
|
|
local color = Color.new(1, 0.5, 0.2, 0.8)
|
|
luaunit.assertEquals(color.r, 1)
|
|
luaunit.assertEquals(color.g, 0.5)
|
|
luaunit.assertEquals(color.b, 0.2)
|
|
luaunit.assertEquals(color.a, 0.8)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorNewDefaults()
|
|
-- Test default values when parameters are nil or missing
|
|
local color = Color.new()
|
|
luaunit.assertEquals(color.r, 0)
|
|
luaunit.assertEquals(color.g, 0)
|
|
luaunit.assertEquals(color.b, 0)
|
|
luaunit.assertEquals(color.a, 1) -- Alpha defaults to 1
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorNewPartialDefaults()
|
|
local color = Color.new(0.7, 0.3)
|
|
luaunit.assertEquals(color.r, 0.7)
|
|
luaunit.assertEquals(color.g, 0.3)
|
|
luaunit.assertEquals(color.b, 0)
|
|
luaunit.assertEquals(color.a, 1)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHex6Digit()
|
|
local color = Color.fromHex("#FF8040")
|
|
-- Note: Color.fromHex actually returns values in 0-255 range, not 0-1
|
|
luaunit.assertEquals(color.r, 255)
|
|
luaunit.assertEquals(color.g, 128)
|
|
luaunit.assertEquals(color.b, 64)
|
|
luaunit.assertEquals(color.a, 1)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHex8Digit()
|
|
local color = Color.fromHex("#FF8040CC")
|
|
luaunit.assertEquals(color.r, 255)
|
|
luaunit.assertEquals(color.g, 128)
|
|
luaunit.assertEquals(color.b, 64)
|
|
luaunit.assertAlmostEquals(color.a, 204/255, 0.01) -- CC hex = 204 decimal
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHexWithoutHash()
|
|
local color = Color.fromHex("FF8040")
|
|
luaunit.assertEquals(color.r, 255)
|
|
luaunit.assertEquals(color.g, 128)
|
|
luaunit.assertEquals(color.b, 64)
|
|
luaunit.assertEquals(color.a, 1)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHexInvalid()
|
|
luaunit.assertError(function()
|
|
Color.fromHex("#INVALID")
|
|
end)
|
|
|
|
luaunit.assertError(function()
|
|
Color.fromHex("#FF80") -- Too short
|
|
end)
|
|
|
|
luaunit.assertError(function()
|
|
Color.fromHex("#FF8040CC99") -- Too long
|
|
end)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorToRGBA()
|
|
local color = Color.new(0.8, 0.6, 0.4, 0.9)
|
|
local r, g, b, a = color:toRGBA()
|
|
luaunit.assertEquals(r, 0.8)
|
|
luaunit.assertEquals(g, 0.6)
|
|
luaunit.assertEquals(b, 0.4)
|
|
luaunit.assertEquals(a, 0.9)
|
|
end
|
|
|
|
-- ============================================
|
|
-- Element Calculation Utility Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testCalculateTextWidthWithText()
|
|
local element = Gui.new({
|
|
text = "Test Text",
|
|
textSize = 16
|
|
})
|
|
|
|
local width = element:calculateTextWidth()
|
|
print("Text: '" .. (element.text or "nil") .. "', TextSize: " .. (element.textSize or "nil") .. ", Width: " .. width)
|
|
luaunit.assertTrue(width > 0, "Text width should be greater than 0, got: " .. width)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateTextWidthNoText()
|
|
local element = Gui.new({})
|
|
|
|
local width = element:calculateTextWidth()
|
|
luaunit.assertEquals(width, 0, "Text width should be 0 when no text")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateTextHeightWithSize()
|
|
local element = Gui.new({
|
|
text = "Test",
|
|
textSize = 24
|
|
})
|
|
|
|
local height = element:calculateTextHeight()
|
|
luaunit.assertTrue(height > 0, "Text height should be greater than 0")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateAutoWidthNoChildren()
|
|
local element = Gui.new({
|
|
text = "Hello"
|
|
})
|
|
|
|
local width = element:calculateAutoWidth()
|
|
local textWidth = element:calculateTextWidth()
|
|
luaunit.assertEquals(width, textWidth, "Auto width should equal text width when no children")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateAutoWidthWithChildren()
|
|
local parent = Gui.new({
|
|
positioning = enums.Positioning.FLEX,
|
|
flexDirection = enums.FlexDirection.HORIZONTAL
|
|
})
|
|
|
|
local child1 = Gui.new({
|
|
parent = parent,
|
|
w = 50,
|
|
h = 30
|
|
})
|
|
|
|
local child2 = Gui.new({
|
|
parent = parent,
|
|
w = 40,
|
|
h = 25
|
|
})
|
|
|
|
local width = parent:calculateAutoWidth()
|
|
luaunit.assertTrue(width > 90, "Auto width should account for children and gaps")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateAutoHeightNoChildren()
|
|
local element = Gui.new({
|
|
text = "Hello"
|
|
})
|
|
|
|
local height = element:calculateAutoHeight()
|
|
local textHeight = element:calculateTextHeight()
|
|
luaunit.assertEquals(height, textHeight, "Auto height should equal text height when no children")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testCalculateAutoHeightWithChildren()
|
|
local parent = Gui.new({
|
|
positioning = enums.Positioning.FLEX,
|
|
flexDirection = enums.FlexDirection.VERTICAL
|
|
})
|
|
|
|
local child1 = Gui.new({
|
|
parent = parent,
|
|
w = 50,
|
|
h = 30
|
|
})
|
|
|
|
local child2 = Gui.new({
|
|
parent = parent,
|
|
w = 40,
|
|
h = 25
|
|
})
|
|
|
|
local height = parent:calculateAutoHeight()
|
|
luaunit.assertTrue(height > 55, "Auto height should account for children and gaps")
|
|
end
|
|
|
|
-- ============================================
|
|
-- Element Utility Methods Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testGetBounds()
|
|
local element = Gui.new({
|
|
x = 10,
|
|
y = 20,
|
|
w = 100,
|
|
h = 80
|
|
})
|
|
|
|
local bounds = element:getBounds()
|
|
luaunit.assertEquals(bounds.x, 10)
|
|
luaunit.assertEquals(bounds.y, 20)
|
|
luaunit.assertEquals(bounds.width, 100)
|
|
luaunit.assertEquals(bounds.height, 80)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateText()
|
|
local element = Gui.new({
|
|
text = "Original Text",
|
|
w = 100,
|
|
h = 50
|
|
})
|
|
|
|
element:updateText("New Text")
|
|
luaunit.assertEquals(element.text, "New Text")
|
|
luaunit.assertEquals(element.width, 100) -- Should not change without autoresize
|
|
luaunit.assertEquals(element.height, 50)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateTextWithAutoresize()
|
|
local element = Gui.new({
|
|
text = "Short",
|
|
textSize = 16
|
|
})
|
|
|
|
local originalWidth = element.width
|
|
element:updateText("Much Longer Text That Should Change Width", true)
|
|
|
|
-- Debug: let's see what the values are
|
|
-- print("Original width: " .. originalWidth .. ", New width: " .. element.width)
|
|
luaunit.assertEquals(element.text, "Much Longer Text That Should Change Width")
|
|
luaunit.assertTrue(element.width > originalWidth, "Width should increase with longer text and autoresize. Original: " .. originalWidth .. ", New: " .. element.width)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateTextKeepOriginalWhenNil()
|
|
local element = Gui.new({
|
|
text = "Original Text"
|
|
})
|
|
|
|
element:updateText(nil)
|
|
luaunit.assertEquals(element.text, "Original Text", "Text should remain unchanged when nil is passed")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateOpacitySingle()
|
|
local element = Gui.new({
|
|
opacity = 1.0
|
|
})
|
|
|
|
element:updateOpacity(0.5)
|
|
luaunit.assertEquals(element.opacity, 0.5)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateOpacityPropagateToChildren()
|
|
local parent = Gui.new({
|
|
opacity = 1.0
|
|
})
|
|
|
|
local child1 = Gui.new({
|
|
parent = parent,
|
|
opacity = 1.0
|
|
})
|
|
|
|
local child2 = Gui.new({
|
|
parent = parent,
|
|
opacity = 1.0
|
|
})
|
|
|
|
parent:updateOpacity(0.3)
|
|
|
|
luaunit.assertEquals(parent.opacity, 0.3)
|
|
luaunit.assertEquals(child1.opacity, 0.3)
|
|
luaunit.assertEquals(child2.opacity, 0.3)
|
|
end
|
|
|
|
-- ============================================
|
|
-- Animation Utility Functions Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testAnimationFadeFactory()
|
|
local fadeAnim = Gui.Animation.fade(2.0, 1.0, 0.0)
|
|
|
|
luaunit.assertEquals(fadeAnim.duration, 2.0)
|
|
luaunit.assertEquals(fadeAnim.start.opacity, 1.0)
|
|
luaunit.assertEquals(fadeAnim.final.opacity, 0.0)
|
|
luaunit.assertNotNil(fadeAnim.transform)
|
|
luaunit.assertNotNil(fadeAnim.transition)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationScaleFactory()
|
|
local scaleAnim = Gui.Animation.scale(1.5, {width = 100, height = 50}, {width = 200, height = 100})
|
|
|
|
luaunit.assertEquals(scaleAnim.duration, 1.5)
|
|
luaunit.assertEquals(scaleAnim.start.width, 100)
|
|
luaunit.assertEquals(scaleAnim.start.height, 50)
|
|
luaunit.assertEquals(scaleAnim.final.width, 200)
|
|
luaunit.assertEquals(scaleAnim.final.height, 100)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationInterpolation()
|
|
local fadeAnim = Gui.Animation.fade(1.0, 1.0, 0.0)
|
|
fadeAnim.elapsed = 0.5 -- 50% through animation
|
|
|
|
local result = fadeAnim:interpolate()
|
|
luaunit.assertAlmostEquals(result.opacity, 0.5, 0.01) -- Should be halfway
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationUpdate()
|
|
local fadeAnim = Gui.Animation.fade(1.0, 1.0, 0.0)
|
|
|
|
-- Animation should not be finished initially
|
|
local finished = fadeAnim:update(0.5)
|
|
luaunit.assertFalse(finished)
|
|
luaunit.assertEquals(fadeAnim.elapsed, 0.5)
|
|
|
|
-- Animation should be finished after full duration
|
|
finished = fadeAnim:update(0.6) -- Total 1.1 seconds > 1.0 duration
|
|
luaunit.assertTrue(finished)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationApplyToElement()
|
|
local element = Gui.new({
|
|
w = 100,
|
|
h = 50
|
|
})
|
|
|
|
local fadeAnim = Gui.Animation.fade(1.0, 1.0, 0.0)
|
|
fadeAnim:apply(element)
|
|
|
|
luaunit.assertEquals(element.animation, fadeAnim)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationReplaceExisting()
|
|
local element = Gui.new({
|
|
w = 100,
|
|
h = 50
|
|
})
|
|
|
|
local fadeAnim1 = Gui.Animation.fade(1.0, 1.0, 0.0)
|
|
local fadeAnim2 = Gui.Animation.fade(2.0, 0.5, 1.0)
|
|
|
|
fadeAnim1:apply(element)
|
|
fadeAnim2:apply(element)
|
|
|
|
luaunit.assertEquals(element.animation, fadeAnim2, "Second animation should replace the first")
|
|
end
|
|
|
|
-- ============================================
|
|
-- GUI Management Utility Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testGuiDestroyEmptyState()
|
|
-- Should not error when destroying empty GUI
|
|
Gui.destroy()
|
|
luaunit.assertEquals(#Gui.topElements, 0)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testGuiDestroyWithElements()
|
|
local element1 = Gui.new({
|
|
x = 10,
|
|
y = 10,
|
|
w = 100,
|
|
h = 50
|
|
})
|
|
|
|
local element2 = Gui.new({
|
|
x = 20,
|
|
y = 20,
|
|
w = 80,
|
|
h = 40
|
|
})
|
|
|
|
luaunit.assertEquals(#Gui.topElements, 2)
|
|
|
|
Gui.destroy()
|
|
luaunit.assertEquals(#Gui.topElements, 0)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testGuiDestroyWithNestedElements()
|
|
local parent = Gui.new({
|
|
w = 200,
|
|
h = 100
|
|
})
|
|
|
|
local child1 = Gui.new({
|
|
parent = parent,
|
|
w = 50,
|
|
h = 30
|
|
})
|
|
|
|
local child2 = Gui.new({
|
|
parent = parent,
|
|
w = 40,
|
|
h = 25
|
|
})
|
|
|
|
luaunit.assertEquals(#Gui.topElements, 1)
|
|
luaunit.assertEquals(#parent.children, 2)
|
|
|
|
Gui.destroy()
|
|
luaunit.assertEquals(#Gui.topElements, 0)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testElementDestroyRemovesFromParent()
|
|
local parent = Gui.new({
|
|
w = 200,
|
|
h = 100
|
|
})
|
|
|
|
local child = Gui.new({
|
|
parent = parent,
|
|
w = 50,
|
|
h = 30
|
|
})
|
|
|
|
luaunit.assertEquals(#parent.children, 1)
|
|
|
|
child:destroy()
|
|
|
|
luaunit.assertEquals(#parent.children, 0)
|
|
luaunit.assertNil(child.parent)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testElementDestroyRemovesFromTopElements()
|
|
local element = Gui.new({
|
|
x = 10,
|
|
y = 10,
|
|
w = 100,
|
|
h = 50
|
|
})
|
|
|
|
luaunit.assertEquals(#Gui.topElements, 1)
|
|
|
|
element:destroy()
|
|
|
|
luaunit.assertEquals(#Gui.topElements, 0)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testElementDestroyNestedChildren()
|
|
local parent = Gui.new({
|
|
w = 200,
|
|
h = 150
|
|
})
|
|
|
|
local child = Gui.new({
|
|
parent = parent,
|
|
w = 100,
|
|
h = 75
|
|
})
|
|
|
|
local grandchild = Gui.new({
|
|
parent = child,
|
|
w = 50,
|
|
h = 30
|
|
})
|
|
|
|
luaunit.assertEquals(#parent.children, 1)
|
|
luaunit.assertEquals(#child.children, 1)
|
|
|
|
parent:destroy()
|
|
|
|
luaunit.assertEquals(#Gui.topElements, 0)
|
|
luaunit.assertEquals(#child.children, 0, "Grandchildren should be destroyed")
|
|
end
|
|
|
|
-- ============================================
|
|
-- Edge Cases and Error Handling Tests
|
|
-- ============================================
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHexEmptyString()
|
|
luaunit.assertError(function()
|
|
Color.fromHex("")
|
|
end)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testColorFromHexNoHashInvalidLength()
|
|
luaunit.assertError(function()
|
|
Color.fromHex("FF80")
|
|
end)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAnimationInterpolationAtBoundaries()
|
|
local scaleAnim = Gui.Animation.scale(1.0, {width = 100, height = 50}, {width = 200, height = 100})
|
|
|
|
-- At start (elapsed = 0)
|
|
scaleAnim.elapsed = 0
|
|
local result = scaleAnim:interpolate()
|
|
luaunit.assertEquals(result.width, 100)
|
|
luaunit.assertEquals(result.height, 50)
|
|
|
|
-- At end (elapsed = duration)
|
|
scaleAnim.elapsed = 1.0
|
|
result = scaleAnim:interpolate()
|
|
luaunit.assertEquals(result.width, 200)
|
|
luaunit.assertEquals(result.height, 100)
|
|
|
|
-- Beyond end (elapsed > duration) - should clamp to end values
|
|
scaleAnim.elapsed = 1.5
|
|
result = scaleAnim:interpolate()
|
|
luaunit.assertEquals(result.width, 200)
|
|
luaunit.assertEquals(result.height, 100)
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testAutoSizingWithZeroChildren()
|
|
local element = Gui.new({
|
|
text = ""
|
|
})
|
|
|
|
local width = element:calculateAutoWidth()
|
|
local height = element:calculateAutoHeight()
|
|
|
|
luaunit.assertTrue(width >= 0, "Auto width should be non-negative")
|
|
luaunit.assertTrue(height >= 0, "Auto height should be non-negative")
|
|
end
|
|
|
|
function TestAuxiliaryFunctions:testUpdateOpacityBoundaryValues()
|
|
local element = Gui.new({
|
|
opacity = 0.5
|
|
})
|
|
|
|
-- Test minimum boundary
|
|
element:updateOpacity(0.0)
|
|
luaunit.assertEquals(element.opacity, 0.0)
|
|
|
|
-- Test maximum boundary
|
|
element:updateOpacity(1.0)
|
|
luaunit.assertEquals(element.opacity, 1.0)
|
|
|
|
-- Test beyond boundaries (should still work, implementation may clamp)
|
|
element:updateOpacity(1.5)
|
|
luaunit.assertEquals(element.opacity, 1.5) -- FlexLove doesn't appear to clamp
|
|
|
|
element:updateOpacity(-0.2)
|
|
luaunit.assertEquals(element.opacity, -0.2) -- FlexLove doesn't appear to clamp
|
|
end
|
|
|
|
-- Run the tests
|
|
os.exit(luaunit.LuaUnit.run()) |