tests
This commit is contained in:
35
FlexLove.lua
35
FlexLove.lua
@@ -596,21 +596,21 @@ function Element:layoutChildren()
|
||||
goto continue
|
||||
end
|
||||
|
||||
if self.flexDirection == FlexDirection.VERTICAL then
|
||||
-- Position relative to parent origin
|
||||
child.x = self.x + (self.margin.left or 0)
|
||||
child.y = self.y + currentPos
|
||||
if self.flexDirection == FlexDirection.VERTICAL then
|
||||
-- Position relative to parent origin
|
||||
child.x = self.x + (self.padding.left or 0)
|
||||
child.y = self.y + currentPos + (self.padding.top or 0)
|
||||
|
||||
-- Apply alignment to vertical axis (alignItems)
|
||||
if self.alignItems == AlignItems.FLEX_START then
|
||||
-- nothing
|
||||
elseif self.alignItems == AlignItems.CENTER then
|
||||
child.x = self.x + (self.width - (child.width or 0)) / 2
|
||||
elseif self.alignItems == AlignItems.FLEX_END then
|
||||
child.x = self.x + self.width - (child.width or 0)
|
||||
elseif self.alignItems == AlignItems.STRETCH then
|
||||
child.width = self.width
|
||||
end
|
||||
-- Apply alignment to vertical axis (alignItems)
|
||||
if self.alignItems == AlignItems.FLEX_START then
|
||||
-- nothing
|
||||
elseif self.alignItems == AlignItems.CENTER then
|
||||
child.x = self.x + ((self.width - (child.width or 0)) / 2)
|
||||
elseif self.alignItems == AlignItems.FLEX_END then
|
||||
child.x = self.x + self.width - (child.width or 0)
|
||||
elseif self.alignItems == AlignItems.STRETCH then
|
||||
child.width = self.width
|
||||
end
|
||||
|
||||
-- Apply self alignment to cross axis (alignSelf)
|
||||
local effectiveAlignSelf = child.alignSelf
|
||||
@@ -650,8 +650,8 @@ function Element:layoutChildren()
|
||||
currentPos = currentPos + (child.height or 0) + self.gap + (self.margin.top or 0) + (self.margin.bottom or 0)
|
||||
else
|
||||
-- Horizontal layout: position relative to parent origin
|
||||
child.x = self.x + currentPos + (self.margin.left or 0)
|
||||
child.y = self.y + (self.margin.top or 0)
|
||||
child.x = self.x + self.padding.left + currentPos
|
||||
child.y = self.y + self.padding.top
|
||||
|
||||
-- Determine effective alignment - alignSelf takes precedence over alignItems
|
||||
local effectiveAlign = child.alignSelf
|
||||
@@ -663,7 +663,8 @@ function Element:layoutChildren()
|
||||
if effectiveAlign == AlignItems.FLEX_START then
|
||||
-- Keep the margin.top position (already applied)
|
||||
elseif effectiveAlign == AlignItems.CENTER then
|
||||
child.y = self.y + (self.height - (child.height or 0)) / 2
|
||||
-- Account for parent's margin when centering vertically
|
||||
child.y = self.y + ((self.height - (child.height or 0)) / 2)
|
||||
elseif effectiveAlign == AlignItems.FLEX_END then
|
||||
child.y = self.y + self.height - (child.height or 0)
|
||||
elseif effectiveAlign == AlignItems.STRETCH then
|
||||
|
||||
142
testing/__tests__/01_absolute_positioning.lua
Normal file
142
testing/__tests__/01_absolute_positioning.lua
Normal file
@@ -0,0 +1,142 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
-- Create test cases
|
||||
TestAbsolutePositioning = {}
|
||||
|
||||
function TestAbsolutePositioning:setUp()
|
||||
-- Reset layout engine before each test
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestAbsolutePositioning:testBasicAbsolutePositioning()
|
||||
-- Test basic absolute positioning - similar to CSS position: absolute
|
||||
local element = self.GUI.new({
|
||||
x = 100,
|
||||
y = 150,
|
||||
w = 200,
|
||||
h = 100,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
luaunit.assertEquals(element.x, 100)
|
||||
luaunit.assertEquals(element.y, 150)
|
||||
luaunit.assertEquals(element.width, 200)
|
||||
luaunit.assertEquals(element.height, 100)
|
||||
luaunit.assertEquals(element.positioning, FlexLove.enums.Positioning.ABSOLUTE)
|
||||
end
|
||||
|
||||
function TestAbsolutePositioning:testAbsolutePositioningWithOffsets()
|
||||
-- Test absolute positioning with top/left/right/bottom - like CSS absolute positioning
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
x = 50,
|
||||
y = 75,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Element should maintain its absolute position
|
||||
luaunit.assertEquals(child.x, 50)
|
||||
luaunit.assertEquals(child.y, 75)
|
||||
luaunit.assertEquals(child.width, 100)
|
||||
luaunit.assertEquals(child.height, 50)
|
||||
end
|
||||
|
||||
function TestAbsolutePositioning:testAbsolutePositioningInContainer()
|
||||
-- Test absolute positioning within a container - similar to CSS relative container
|
||||
local container = self.GUI.new({
|
||||
x = 100,
|
||||
y = 100,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
x = 50,
|
||||
y = 50,
|
||||
w = 100,
|
||||
h = 100,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Child should keep its absolute position
|
||||
luaunit.assertEquals(child.x, 50)
|
||||
luaunit.assertEquals(child.y, 50)
|
||||
luaunit.assertEquals(child.width, 100)
|
||||
luaunit.assertEquals(child.height, 100)
|
||||
end
|
||||
|
||||
function TestAbsolutePositioning:testAbsolutePositioningWithRightBottom()
|
||||
-- Test absolute positioning with right/bottom properties - like CSS
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1000,
|
||||
h = 800,
|
||||
})
|
||||
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
x = 850,
|
||||
y = 650,
|
||||
w = 100,
|
||||
h = 100,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Child should maintain its position from right/bottom edges
|
||||
luaunit.assertEquals(child.x, 850)
|
||||
luaunit.assertEquals(child.y, 650)
|
||||
luaunit.assertEquals(child.width, 100)
|
||||
luaunit.assertEquals(child.height, 100)
|
||||
end
|
||||
|
||||
function TestAbsolutePositioning:testAbsolutePositioningZIndex()
|
||||
-- Test z-index with absolute positioning - like CSS z-index
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
z = 1,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
x = 50,
|
||||
y = 50,
|
||||
w = 100,
|
||||
h = 100,
|
||||
z = 2,
|
||||
positioning = FlexLove.enums.Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Elements should maintain their z-index order
|
||||
luaunit.assertEquals(child1.z, 1)
|
||||
luaunit.assertEquals(child2.z, 2)
|
||||
luaunit.assertTrue(child1.z < child2.z)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
217
testing/__tests__/02_flex_direction.lua
Normal file
217
testing/__tests__/02_flex_direction.lua
Normal file
@@ -0,0 +1,217 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local JustifyContent = FlexLove.enums.JustifyContent
|
||||
local AlignItems = FlexLove.enums.AlignItems
|
||||
|
||||
-- Create test cases
|
||||
TestFlexDirection = {}
|
||||
|
||||
function TestFlexDirection:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexBasic()
|
||||
-- Test basic horizontal flex layout - like CSS flex-direction: row
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
})
|
||||
|
||||
-- Add three children with equal widths
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Elements should be positioned horizontally with default gap of 10
|
||||
luaunit.assertEquals(child1.x, 0) -- First child starts at container's x
|
||||
luaunit.assertEquals(child2.x, 110) -- Second child starts after first child + gap
|
||||
luaunit.assertEquals(child3.x, 220) -- Third child starts after second child + gap
|
||||
|
||||
-- All children should maintain their original widths
|
||||
luaunit.assertEquals(child1.width, 100)
|
||||
luaunit.assertEquals(child2.width, 100)
|
||||
luaunit.assertEquals(child3.width, 100)
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexWithJustifyContentFlexStart()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add three children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be positioned at the start with default gap
|
||||
luaunit.assertEquals(child1.x, 0)
|
||||
luaunit.assertEquals(child2.x, 60)
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexWithJustifyContentCenter()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.CENTER,
|
||||
})
|
||||
|
||||
-- Add three children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be centered in container
|
||||
-- Total width used: 50 + 10 + 50 = 110px
|
||||
-- Remaining space: 500 - 110 = 390px
|
||||
-- Space before first child: 390/2 = 195px
|
||||
luaunit.assertEquals(child1.x, 195)
|
||||
luaunit.assertEquals(child2.x, 255) -- 195 + 50 + 10
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexWithJustifyContentFlexEnd()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.FLEX_END,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be positioned at the end
|
||||
-- Total width used: 50 + 10 + 50 = 110px
|
||||
-- First child should start at: 500 - 110 = 390px
|
||||
luaunit.assertEquals(child1.x, 390)
|
||||
luaunit.assertEquals(child2.x, 450) -- 390 + 50 + 10
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexWithJustifyContentSpaceBetween()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_BETWEEN,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be positioned at the edges
|
||||
luaunit.assertEquals(child1.x, 0)
|
||||
luaunit.assertEquals(child2.x, 450)
|
||||
end
|
||||
|
||||
function TestFlexDirection:testHorizontalFlexWithAlignItemsCenter()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
-- Add a child shorter than the container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50, -- Container is 100px high, child is 50px
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be vertically centered
|
||||
-- Container height: 100px, Child height: 50px
|
||||
-- Expected y: (100 - 50) / 2 = 25px
|
||||
luaunit.assertEquals(child.y, 25)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
175
testing/__tests__/03_vertical_flex_direction.lua
Normal file
175
testing/__tests__/03_vertical_flex_direction.lua
Normal file
@@ -0,0 +1,175 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local JustifyContent = FlexLove.enums.JustifyContent
|
||||
local AlignItems = FlexLove.enums.AlignItems
|
||||
|
||||
-- Create test cases
|
||||
TestVerticalFlexDirection = {}
|
||||
|
||||
function TestVerticalFlexDirection:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestVerticalFlexDirection:testVerticalFlexBasic()
|
||||
-- Test basic vertical flex layout - like CSS flex-direction: column
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 500,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
-- Add three children with equal heights
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Elements should be positioned vertically with default gap of 10
|
||||
luaunit.assertEquals(child1.y, 0)
|
||||
luaunit.assertEquals(child2.y, 110)
|
||||
luaunit.assertEquals(child3.y, 220)
|
||||
|
||||
-- All children should maintain their original heights
|
||||
luaunit.assertEquals(child1.height, 100)
|
||||
luaunit.assertEquals(child2.height, 100)
|
||||
luaunit.assertEquals(child3.height, 100)
|
||||
end
|
||||
|
||||
function TestVerticalFlexDirection:testVerticalFlexWithJustifyContentFlexStart()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 500,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
justifyContent = JustifyContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be positioned at the start with default gap
|
||||
luaunit.assertEquals(child1.y, 0)
|
||||
luaunit.assertEquals(child2.y, 60)
|
||||
end
|
||||
|
||||
function TestVerticalFlexDirection:testVerticalFlexWithJustifyContentCenter()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 500,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
justifyContent = JustifyContent.CENTER,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be centered in container
|
||||
-- Total height used: 50 + 10 + 50 = 110px
|
||||
-- Remaining space: 500 - 110 = 390px
|
||||
-- Space before first child: 390/2 = 195px
|
||||
luaunit.assertEquals(child1.y, 195)
|
||||
luaunit.assertEquals(child2.y, 255)
|
||||
end
|
||||
|
||||
function TestVerticalFlexDirection:testVerticalFlexWithAlignItemsCenter()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 500,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
-- Add a child narrower than the container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be horizontally centered
|
||||
-- Container width: 100px, Child width: 50px
|
||||
-- Expected x: (100 - 50) / 2 = 25px
|
||||
luaunit.assertEquals(child.x, 25)
|
||||
end
|
||||
|
||||
function TestVerticalFlexDirection:testVerticalFlexWithAlignItemsStretch()
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 500,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignItems = AlignItems.STRETCH,
|
||||
})
|
||||
|
||||
-- Add a child without explicit width
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should stretch to container width
|
||||
luaunit.assertEquals(child.width, 100)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
206
testing/__tests__/04_justify_content.lua
Normal file
206
testing/__tests__/04_justify_content.lua
Normal file
@@ -0,0 +1,206 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local JustifyContent = FlexLove.enums.JustifyContent
|
||||
|
||||
-- Create test cases
|
||||
TestJustifyContent = {}
|
||||
|
||||
function TestJustifyContent:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestJustifyContent:testJustifyContentSpaceEvenly()
|
||||
-- Test space-evenly distribution in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_EVENLY,
|
||||
})
|
||||
|
||||
-- Add three children of equal width
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Calculate expected positions
|
||||
-- Total width of children: 150px (3 * 50px)
|
||||
-- Remaining space: 150px (300px - 150px)
|
||||
-- Space between and around items: 150px / 4 = 37.5px
|
||||
luaunit.assertEquals(child1.x, 37) -- First space
|
||||
luaunit.assertEquals(child2.x, 125) -- First space + width + second space
|
||||
luaunit.assertEquals(child3.x, 212) -- Previous + width + third space
|
||||
end
|
||||
|
||||
function TestJustifyContent:testJustifyContentSpaceAround()
|
||||
-- Test space-around distribution
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_AROUND,
|
||||
})
|
||||
|
||||
-- Add two children with equal widths
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Calculate expected positions
|
||||
-- Total width of children: 100px (2 * 50px)
|
||||
-- Remaining space: 200px (300px - 100px)
|
||||
-- Space around each item: 200px / 4 = 50px
|
||||
-- First item gets 50px margin, second gets 150px (50px * 3) margin
|
||||
luaunit.assertEquals(child1.x, 50)
|
||||
luaunit.assertEquals(child2.x, 200)
|
||||
end
|
||||
|
||||
function TestJustifyContent:testJustifyContentSpaceBetween()
|
||||
-- Test space-between distribution
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_BETWEEN,
|
||||
})
|
||||
|
||||
-- Add three children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Calculate expected positions
|
||||
-- Total width of children: 150px (3 * 50px)
|
||||
-- Remaining space: 150px (300px - 150px)
|
||||
-- Space between items: 75px (150px / 2)
|
||||
luaunit.assertEquals(child1.x, 0) -- First child at start
|
||||
luaunit.assertEquals(child2.x, 125) -- After first gap
|
||||
luaunit.assertEquals(child3.x, 250) -- After second gap
|
||||
end
|
||||
|
||||
function TestJustifyContent:testJustifyContentFlexStart()
|
||||
-- Test flex-start alignment
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be at the start with default gap
|
||||
luaunit.assertEquals(child1.x, 0) -- First child at start
|
||||
luaunit.assertEquals(child2.x, 60) -- After first child + gap
|
||||
end
|
||||
|
||||
function TestJustifyContent:testJustifyContentFlexEnd()
|
||||
-- Test flex-end alignment
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.FLEX_END,
|
||||
})
|
||||
|
||||
-- Add two children
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Children should be at the end with default gap
|
||||
-- Total width needed: 110px (50px + 10px + 50px)
|
||||
-- Start position: 300px - 110px = 190px
|
||||
luaunit.assertEquals(child1.x, 190)
|
||||
luaunit.assertEquals(child2.x, 250)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
168
testing/__tests__/05_align_items.lua
Normal file
168
testing/__tests__/05_align_items.lua
Normal file
@@ -0,0 +1,168 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local AlignItems = FlexLove.enums.AlignItems
|
||||
|
||||
-- Create test cases
|
||||
TestAlignItems = {}
|
||||
|
||||
function TestAlignItems:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsStretchHorizontal()
|
||||
-- Test stretch alignment in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.STRETCH,
|
||||
})
|
||||
|
||||
-- Add child without explicit height
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should stretch to container height
|
||||
luaunit.assertEquals(child.height, container.height)
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsStretchVertical()
|
||||
-- Test stretch alignment in vertical layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignItems = AlignItems.STRETCH,
|
||||
})
|
||||
|
||||
-- Add child without explicit width
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should stretch to container width
|
||||
luaunit.assertEquals(child.width, container.width)
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsCenterHorizontal()
|
||||
-- Test center alignment in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
-- Add child shorter than container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be vertically centered
|
||||
-- Container height: 100px, Child height: 50px
|
||||
-- Expected y: (100 - 50) / 2 = 25px
|
||||
luaunit.assertEquals(child.y, 25)
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsCenterVertical()
|
||||
-- Test center alignment in vertical layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
-- Add child narrower than container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be horizontally centered
|
||||
-- Container width: 100px, Child width: 50px
|
||||
-- Expected x: (100 - 50) / 2 = 25px
|
||||
luaunit.assertEquals(child.x, 25)
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsFlexStart()
|
||||
-- Test flex-start alignment in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add child shorter than container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be at the top
|
||||
luaunit.assertEquals(child.y, 0)
|
||||
end
|
||||
|
||||
function TestAlignItems:testAlignItemsFlexEnd()
|
||||
-- Test flex-end alignment in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.FLEX_END,
|
||||
})
|
||||
|
||||
-- Add child shorter than container
|
||||
local child = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Child should be at the bottom
|
||||
-- Container height: 100px, Child height: 50px
|
||||
-- Expected y: 100px - 50px = 50px
|
||||
luaunit.assertEquals(child.y, 50)
|
||||
end
|
||||
|
||||
-- Run the test suite
|
||||
os.exit(luaunit.LuaUnit.run())
|
||||
|
||||
234
testing/__tests__/06_flex_wrap.lua
Normal file
234
testing/__tests__/06_flex_wrap.lua
Normal file
@@ -0,0 +1,234 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local AlignContent = FlexLove.enums.AlignContent
|
||||
|
||||
-- Create test cases
|
||||
TestFlexWrap = {}
|
||||
|
||||
function TestFlexWrap:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestFlexWrap:testFlexWrapHorizontal()
|
||||
-- Test flex wrap in horizontal layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignContent = AlignContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add three children that exceed container width
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- First line: child1 and child2 (with 10px gap)
|
||||
-- Second line: child3
|
||||
luaunit.assertEquals(child1.x, 0)
|
||||
luaunit.assertEquals(child1.y, 0)
|
||||
luaunit.assertEquals(child2.x, 60)
|
||||
luaunit.assertEquals(child2.y, 0)
|
||||
luaunit.assertEquals(child3.x, 0)
|
||||
luaunit.assertEquals(child3.y, 60)
|
||||
end
|
||||
|
||||
function TestFlexWrap:testFlexWrapVertical()
|
||||
-- Test flex wrap in vertical layout
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignContent = AlignContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Add three children that exceed container height
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- First column: child1 and child2 (with 10px gap)
|
||||
-- Second column: child3
|
||||
luaunit.assertEquals(child1.x, 0)
|
||||
luaunit.assertEquals(child1.y, 0)
|
||||
luaunit.assertEquals(child2.x, 0)
|
||||
luaunit.assertEquals(child2.y, 60)
|
||||
luaunit.assertEquals(child3.x, 60)
|
||||
luaunit.assertEquals(child3.y, 0)
|
||||
end
|
||||
|
||||
function TestFlexWrap:testFlexWrapWithAlignContentCenter()
|
||||
-- Test align-content center with flex wrap
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignContent = AlignContent.CENTER,
|
||||
})
|
||||
|
||||
-- Add three children that create two rows
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Total height used: 110px (two rows of 50px + 10px gap)
|
||||
-- Remaining space: 190px (300px - 110px)
|
||||
-- Space before first row: 95px (190px / 2)
|
||||
luaunit.assertEquals(child1.y, 95)
|
||||
luaunit.assertEquals(child2.y, 95)
|
||||
luaunit.assertEquals(child3.y, 155) -- 95px + 50px + 10px gap
|
||||
end
|
||||
|
||||
function TestFlexWrap:testFlexWrapWithAlignContentSpaceBetween()
|
||||
-- Test align-content space-between with flex wrap
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignContent = AlignContent.SPACE_BETWEEN,
|
||||
})
|
||||
|
||||
-- Add three children that create two rows
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- First row at top (y = 0)
|
||||
-- Second row at bottom (y = 250)
|
||||
luaunit.assertEquals(child1.y, 0)
|
||||
luaunit.assertEquals(child2.y, 0)
|
||||
luaunit.assertEquals(child3.y, 250)
|
||||
end
|
||||
|
||||
function TestFlexWrap:testFlexWrapWithAlignContentSpaceAround()
|
||||
-- Test align-content space-around with flex wrap
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignContent = AlignContent.SPACE_AROUND,
|
||||
})
|
||||
|
||||
-- Add three children that create two rows
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child3 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Space around calculation:
|
||||
-- Total height of content: 110px (two rows of 50px + 10px gap)
|
||||
-- Remaining space: 190px
|
||||
-- Space per unit: 63.33px (190px / 3)
|
||||
-- First row: 63.33px (one unit of space)
|
||||
-- Second row: 190px (three units of space)
|
||||
luaunit.assertEquals(child1.y, 63)
|
||||
luaunit.assertEquals(child2.y, 63)
|
||||
luaunit.assertEquals(child3.y, 190)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
267
testing/__tests__/07_layout_validation.lua
Normal file
267
testing/__tests__/07_layout_validation.lua
Normal file
@@ -0,0 +1,267 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local JustifyContent = FlexLove.enums.JustifyContent
|
||||
local AlignItems = FlexLove.enums.AlignItems
|
||||
|
||||
-- Create test cases
|
||||
TestLayoutValidation = {}
|
||||
|
||||
function TestLayoutValidation:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestLayoutValidation:testNestedFlexContainers()
|
||||
-- Test nested flex containers behave correctly
|
||||
local outerContainer = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
local innerContainer1 = self.GUI.new({
|
||||
parent = outerContainer,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_BETWEEN,
|
||||
})
|
||||
|
||||
local innerContainer2 = self.GUI.new({
|
||||
parent = outerContainer,
|
||||
w = 300,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.CENTER,
|
||||
})
|
||||
|
||||
-- Add children to inner container 1
|
||||
local child1 = self.GUI.new({
|
||||
parent = innerContainer1,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = innerContainer1,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Add child to inner container 2
|
||||
local child3 = self.GUI.new({
|
||||
parent = innerContainer2,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Verify outer container layout
|
||||
luaunit.assertEquals(innerContainer1.y, 0)
|
||||
luaunit.assertEquals(innerContainer2.y, 110) -- 100 + 10 gap
|
||||
|
||||
-- Verify inner container 1 layout (space-between)
|
||||
luaunit.assertEquals(child1.x, 0)
|
||||
luaunit.assertEquals(child2.x, 250)
|
||||
|
||||
-- Verify inner container 2 layout (center)
|
||||
luaunit.assertEquals(child3.x, 125) -- (300 - 50) / 2
|
||||
|
||||
-- Test container references
|
||||
luaunit.assertEquals(#innerContainer1.children, 2)
|
||||
luaunit.assertEquals(#innerContainer2.children, 1)
|
||||
luaunit.assertEquals(innerContainer1.children[1], child1)
|
||||
luaunit.assertEquals(innerContainer1.children[2], child2)
|
||||
luaunit.assertEquals(innerContainer2.children[1], child3)
|
||||
end
|
||||
|
||||
function TestLayoutValidation:testMixedPositioning()
|
||||
-- Test mixing absolute and flex positioning
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 300,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
-- Add flex positioned child
|
||||
local flexChild = self.GUI.new({
|
||||
parent = container,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Add absolute positioned child
|
||||
local absoluteChild = self.GUI.new({
|
||||
parent = container,
|
||||
x = 150,
|
||||
y = 150,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Add another flex positioned child
|
||||
local flexChild2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 100,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Verify flex children positions
|
||||
luaunit.assertEquals(flexChild.y, 0)
|
||||
luaunit.assertEquals(flexChild2.y, 60) -- 50 + 10 gap
|
||||
|
||||
-- Verify absolute child position is maintained
|
||||
luaunit.assertEquals(absoluteChild.x, 150)
|
||||
luaunit.assertEquals(absoluteChild.y, 150)
|
||||
end
|
||||
|
||||
function TestLayoutValidation:testDynamicSizing()
|
||||
-- Test auto-sizing of flex containers
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
})
|
||||
|
||||
-- Add children to determine container size
|
||||
local child1 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 150,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Container should size to fit children
|
||||
luaunit.assertEquals(container.width, 110) -- 50 + 10 + 50
|
||||
luaunit.assertEquals(container.height, 150) -- Max of child heights
|
||||
end
|
||||
|
||||
function TestLayoutValidation:testDeepNesting()
|
||||
-- Test deeply nested flex containers
|
||||
local level1 = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 400,
|
||||
h = 400,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
local level2 = self.GUI.new({
|
||||
parent = level1,
|
||||
w = 300,
|
||||
h = 300,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
})
|
||||
|
||||
local level3 = self.GUI.new({
|
||||
parent = level2,
|
||||
w = 200,
|
||||
h = 200,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
local level4 = self.GUI.new({
|
||||
parent = level3,
|
||||
w = 100,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.CENTER,
|
||||
})
|
||||
|
||||
-- Add a child to the deepest level
|
||||
local deepChild = self.GUI.new({
|
||||
parent = level4,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Verify positioning through all levels
|
||||
luaunit.assertEquals(level2.y, 0)
|
||||
luaunit.assertEquals(level3.x, 0)
|
||||
luaunit.assertEquals(level4.x, 50) -- (200 - 100) / 2
|
||||
luaunit.assertEquals(deepChild.x, 25) -- (100 - 50) / 2
|
||||
end
|
||||
|
||||
function TestLayoutValidation:testEdgeCases()
|
||||
-- Test edge cases and potential layout issues
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
})
|
||||
|
||||
-- Test zero-size child
|
||||
local zeroSizeChild = self.GUI.new({
|
||||
parent = container,
|
||||
w = 0,
|
||||
h = 0,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Test negative size (should be clamped to 0)
|
||||
local negativeSizeChild = self.GUI.new({
|
||||
parent = container,
|
||||
w = -50,
|
||||
h = -50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Test oversized child
|
||||
local oversizedChild = self.GUI.new({
|
||||
parent = container,
|
||||
w = 200,
|
||||
h = 200,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
|
||||
-- Verify layout handles edge cases gracefully
|
||||
luaunit.assertTrue(zeroSizeChild.width >= 0)
|
||||
luaunit.assertTrue(zeroSizeChild.height >= 0)
|
||||
luaunit.assertTrue(negativeSizeChild.width >= 0)
|
||||
luaunit.assertTrue(negativeSizeChild.height >= 0)
|
||||
luaunit.assertEquals(oversizedChild.x, 0) -- Should still be positioned at start
|
||||
|
||||
-- Check that containers handle children properly
|
||||
luaunit.assertEquals(zeroSizeChild.x, 0) -- First child should be at start
|
||||
luaunit.assertEquals(negativeSizeChild.x, 0) -- Should be positioned after zero-size child
|
||||
luaunit.assertEquals(oversizedChild.x, 0) -- Should be positioned after negative-size child
|
||||
luaunit.assertNotNil(container.children[1]) -- Container should maintain child references
|
||||
luaunit.assertEquals(#container.children, 3) -- All children should be tracked
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
211
testing/__tests__/08_performance.lua
Normal file
211
testing/__tests__/08_performance.lua
Normal file
@@ -0,0 +1,211 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
-- Import only the enum values we need for each test
|
||||
local FlexDirection = FlexLove.enums.FlexDirection
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local JustifyContent = FlexLove.enums.JustifyContent
|
||||
local AlignItems = FlexLove.enums.AlignItems
|
||||
|
||||
-- Create test cases
|
||||
TestPerformance = {}
|
||||
|
||||
function TestPerformance:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
-- Helper function to measure execution time
|
||||
local function measure(fn)
|
||||
local start = os.clock()
|
||||
fn()
|
||||
return os.clock() - start
|
||||
end
|
||||
|
||||
function TestPerformance:testLargeNumberOfChildren()
|
||||
-- Test performance with a large number of children
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1000,
|
||||
h = 1000,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.FLEX_START,
|
||||
})
|
||||
|
||||
-- Create 100 children
|
||||
local createTime = measure(function()
|
||||
for _ = 1, 100 do
|
||||
self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Print creation time for visibility
|
||||
print(string.format("Creating 100 children took: %.4f seconds", createTime))
|
||||
|
||||
-- Verify container has all children
|
||||
luaunit.assertEquals(#container.children, 100)
|
||||
|
||||
-- Performance should be reasonable (adjust threshold based on target hardware)
|
||||
luaunit.assertTrue(createTime < 1.0, "Creating children took too long: " .. createTime)
|
||||
|
||||
-- Test layout time (with nil check)
|
||||
local layoutTime = measure(function()
|
||||
luaunit.assertNotNil(container.layoutChildren, "layoutChildren method should exist")
|
||||
container:layoutChildren()
|
||||
end)
|
||||
|
||||
-- Print layout time for visibility
|
||||
print(string.format("Laying out 100 children took: %.4f seconds", layoutTime))
|
||||
|
||||
-- Layout should be reasonably fast
|
||||
luaunit.assertTrue(layoutTime < 1.0, "Layout took too long: " .. layoutTime)
|
||||
end
|
||||
|
||||
function TestPerformance:testDeepHierarchy()
|
||||
-- Test performance with a deep hierarchy
|
||||
local root = nil
|
||||
local rootTime = measure(function()
|
||||
root = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1000,
|
||||
h = 1000,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
local current = root
|
||||
for i = 1, 10 do
|
||||
current = self.GUI.new({
|
||||
parent = current,
|
||||
w = 900 - (i * 50),
|
||||
h = 900 - (i * 50),
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = i % 2 == 0 and FlexDirection.HORIZONTAL or FlexDirection.VERTICAL,
|
||||
})
|
||||
|
||||
-- Add some siblings at each level
|
||||
for _ = 1, 3 do
|
||||
self.GUI.new({
|
||||
parent = current,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Print creation time for visibility
|
||||
print(string.format("Creating deep hierarchy took: %.4f seconds", rootTime))
|
||||
|
||||
-- Creation should be reasonably fast
|
||||
luaunit.assertTrue(rootTime < 1.0, "Creating deep hierarchy took too long: " .. rootTime)
|
||||
|
||||
-- Test layout performance (with nil check)
|
||||
local layoutTime = measure(function()
|
||||
luaunit.assertNotNil(root.layoutChildren, "layoutChildren method should exist")
|
||||
root:layoutChildren()
|
||||
end)
|
||||
|
||||
-- Print layout time for visibility
|
||||
print(string.format("Laying out deep hierarchy took: %.4f seconds", layoutTime))
|
||||
|
||||
-- Layout should be reasonably fast
|
||||
luaunit.assertTrue(layoutTime < 1.0, "Layout took too long: " .. layoutTime)
|
||||
end
|
||||
|
||||
function TestPerformance:testDynamicUpdates()
|
||||
-- Test performance of dynamic updates
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1000,
|
||||
h = 1000,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
alignItems = AlignItems.CENTER,
|
||||
})
|
||||
|
||||
-- Create 50 children
|
||||
local children = {}
|
||||
for i = 1, 50 do
|
||||
children[i] = self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
end
|
||||
|
||||
-- Test update performance (resizing children)
|
||||
local updateTime = measure(function()
|
||||
for _, child in ipairs(children) do
|
||||
child.width = child.width + 10
|
||||
child.height = child.height + 10
|
||||
end
|
||||
luaunit.assertNotNil(container.layoutChildren, "layoutChildren method should exist")
|
||||
container:layoutChildren()
|
||||
end)
|
||||
|
||||
-- Print update time for visibility
|
||||
print(string.format("Updating 50 children took: %.4f seconds", updateTime))
|
||||
|
||||
-- Updates should be reasonably fast
|
||||
luaunit.assertTrue(updateTime < 1.0, "Updates took too long: " .. updateTime)
|
||||
|
||||
-- Verify updates were applied
|
||||
luaunit.assertEquals(children[1].width, 60)
|
||||
luaunit.assertEquals(children[1].height, 60)
|
||||
end
|
||||
|
||||
function TestPerformance:testRapidResizing()
|
||||
-- Test performance of rapid window resizing
|
||||
local container = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1000,
|
||||
h = 1000,
|
||||
positioning = Positioning.FLEX,
|
||||
flexDirection = FlexDirection.HORIZONTAL,
|
||||
justifyContent = JustifyContent.SPACE_BETWEEN,
|
||||
})
|
||||
|
||||
-- Add 20 children
|
||||
for _ = 1, 20 do
|
||||
self.GUI.new({
|
||||
parent = container,
|
||||
w = 50,
|
||||
h = 50,
|
||||
positioning = Positioning.FLEX,
|
||||
})
|
||||
end
|
||||
|
||||
-- Test 10 rapid resizes
|
||||
local resizeTime = measure(function()
|
||||
for i = 1, 10 do
|
||||
container:resize(1000 + i * 100, 1000 + i * 100)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Print resize time for visibility
|
||||
print(string.format("10 rapid resizes took: %.4f seconds", resizeTime))
|
||||
|
||||
-- Resizing should be reasonably fast
|
||||
luaunit.assertTrue(resizeTime < 1.0, "Resizing took too long: " .. resizeTime)
|
||||
|
||||
-- Verify final dimensions
|
||||
luaunit.assertEquals(container.width, 2000)
|
||||
luaunit.assertEquals(container.height, 2000)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
230
testing/__tests__/09_element_properties.lua
Normal file
230
testing/__tests__/09_element_properties.lua
Normal file
@@ -0,0 +1,230 @@
|
||||
package.path = package.path .. ";game/libs/?.lua;?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local Positioning = FlexLove.enums.Positioning
|
||||
local TextAlign = FlexLove.enums.TextAlign
|
||||
local Color = FlexLove.Color
|
||||
|
||||
-- Create test cases
|
||||
TestElementProperties = {}
|
||||
|
||||
function TestElementProperties:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestElementProperties:testBasicProperties()
|
||||
local element = self.GUI.new({
|
||||
x = 10,
|
||||
y = 20,
|
||||
w = 100,
|
||||
h = 50,
|
||||
z = 1,
|
||||
positioning = Positioning.ABSOLUTE,
|
||||
})
|
||||
|
||||
-- Test basic properties
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertEquals(element.x, 10)
|
||||
luaunit.assertEquals(element.y, 20)
|
||||
luaunit.assertEquals(element.z, 1)
|
||||
luaunit.assertEquals(element.width, 100)
|
||||
luaunit.assertEquals(element.height, 50)
|
||||
luaunit.assertEquals(element.positioning, Positioning.ABSOLUTE)
|
||||
end
|
||||
|
||||
function TestElementProperties:testPropertyModification()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test property modification
|
||||
luaunit.assertNotNil(element)
|
||||
element.x = 50
|
||||
element.y = 60
|
||||
element.width = 200
|
||||
element.height = 150
|
||||
|
||||
luaunit.assertEquals(element.x, 50)
|
||||
luaunit.assertEquals(element.y, 60)
|
||||
luaunit.assertEquals(element.width, 200)
|
||||
luaunit.assertEquals(element.height, 150)
|
||||
end
|
||||
|
||||
function TestElementProperties:testParentChildRelationship()
|
||||
local parent = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child = self.GUI.new({
|
||||
parent = parent,
|
||||
x = 10,
|
||||
y = 10,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test parent-child relationship
|
||||
luaunit.assertNotNil(parent)
|
||||
luaunit.assertNotNil(child)
|
||||
luaunit.assertNotNil(parent.children)
|
||||
luaunit.assertEquals(child.parent, parent)
|
||||
luaunit.assertTrue(#parent.children == 1)
|
||||
luaunit.assertEquals(parent.children[1], child)
|
||||
end
|
||||
|
||||
function TestElementProperties:testBounds()
|
||||
local element = self.GUI.new({
|
||||
x = 10,
|
||||
y = 20,
|
||||
w = 100,
|
||||
h = 50,
|
||||
})
|
||||
|
||||
-- Test bounds calculation
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.getBounds)
|
||||
local bounds = element:getBounds()
|
||||
luaunit.assertEquals(bounds.x, 10)
|
||||
luaunit.assertEquals(bounds.y, 20)
|
||||
luaunit.assertEquals(bounds.width, 100)
|
||||
luaunit.assertEquals(bounds.height, 50)
|
||||
end
|
||||
|
||||
function TestElementProperties:testZLayering()
|
||||
local parent = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child1 = self.GUI.new({
|
||||
parent = parent,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
z = 1,
|
||||
})
|
||||
|
||||
local child2 = self.GUI.new({
|
||||
parent = parent,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
z = 2,
|
||||
})
|
||||
|
||||
-- Test z ordering
|
||||
luaunit.assertNotNil(parent)
|
||||
luaunit.assertNotNil(child1)
|
||||
luaunit.assertNotNil(child2)
|
||||
luaunit.assertNotNil(child1.z)
|
||||
luaunit.assertNotNil(child2.z)
|
||||
luaunit.assertTrue(child1.z < child2.z)
|
||||
end
|
||||
|
||||
function TestElementProperties:testColors()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
background = Color.new(1, 0, 0, 1), -- Red
|
||||
textColor = Color.new(0, 1, 0, 1), -- Green
|
||||
borderColor = Color.new(0, 0, 1, 1), -- Blue
|
||||
})
|
||||
|
||||
-- Test color assignments
|
||||
luaunit.assertNotNil(element.background)
|
||||
luaunit.assertEquals(element.background.r, 1)
|
||||
luaunit.assertEquals(element.background.g, 0)
|
||||
luaunit.assertEquals(element.background.b, 0)
|
||||
luaunit.assertEquals(element.background.a, 1)
|
||||
|
||||
luaunit.assertNotNil(element.textColor)
|
||||
luaunit.assertEquals(element.textColor.r, 0)
|
||||
luaunit.assertEquals(element.textColor.g, 1)
|
||||
luaunit.assertEquals(element.textColor.b, 0)
|
||||
luaunit.assertEquals(element.textColor.a, 1)
|
||||
|
||||
luaunit.assertNotNil(element.borderColor)
|
||||
luaunit.assertEquals(element.borderColor.r, 0)
|
||||
luaunit.assertEquals(element.borderColor.g, 0)
|
||||
luaunit.assertEquals(element.borderColor.b, 1)
|
||||
luaunit.assertEquals(element.borderColor.a, 1)
|
||||
end
|
||||
|
||||
function TestElementProperties:testText()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 200,
|
||||
h = 100,
|
||||
text = "Test Text",
|
||||
textSize = 16,
|
||||
textAlign = TextAlign.CENTER,
|
||||
})
|
||||
|
||||
-- Test text properties
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertEquals(element.text, "Test Text")
|
||||
luaunit.assertEquals(element.textSize, 16)
|
||||
luaunit.assertEquals(element.textAlign, TextAlign.CENTER)
|
||||
|
||||
-- Test text update
|
||||
element:updateText("New Text", true)
|
||||
luaunit.assertEquals(element.text, "New Text")
|
||||
end
|
||||
|
||||
function TestElementProperties:testOpacity()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
opacity = 0.5,
|
||||
})
|
||||
|
||||
-- Test opacity property and updates
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertEquals(element.opacity, 0.5)
|
||||
|
||||
element:updateOpacity(0.8)
|
||||
luaunit.assertEquals(element.opacity, 0.8)
|
||||
end
|
||||
|
||||
function TestElementProperties:testBorder()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
border = {
|
||||
top = true,
|
||||
right = true,
|
||||
bottom = true,
|
||||
left = true,
|
||||
},
|
||||
})
|
||||
|
||||
-- Test border configuration
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertTrue(element.border.top)
|
||||
luaunit.assertTrue(element.border.right)
|
||||
luaunit.assertTrue(element.border.bottom)
|
||||
luaunit.assertTrue(element.border.left)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
|
||||
216
testing/__tests__/10_animation_and_transform.lua
Normal file
216
testing/__tests__/10_animation_and_transform.lua
Normal file
@@ -0,0 +1,216 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
-- Create test cases
|
||||
TestAnimationAndTransform = {}
|
||||
|
||||
function TestAnimationAndTransform:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testBasicTranslation()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test translate transformation
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.translate)
|
||||
element:translate(50, 30)
|
||||
luaunit.assertEquals(element.x, 50)
|
||||
luaunit.assertEquals(element.y, 30)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testScale()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test scale transformation
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.scale)
|
||||
element:scale(2, 1.5)
|
||||
luaunit.assertEquals(element.width, 200)
|
||||
luaunit.assertEquals(element.height, 150)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testRotation()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test rotation transformation (in radians)
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.rotate)
|
||||
local angle = math.pi / 4 -- 45 degrees
|
||||
element:rotate(angle)
|
||||
luaunit.assertNotNil(element.rotation)
|
||||
luaunit.assertEquals(element.rotation, angle)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testAnimationTweening()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Start position animation
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.animate)
|
||||
luaunit.assertNotNil(element.update)
|
||||
element:animate({
|
||||
x = 200,
|
||||
y = 150,
|
||||
duration = 1.0,
|
||||
easing = "linear",
|
||||
})
|
||||
|
||||
-- Test initial state
|
||||
luaunit.assertEquals(element.x, 0)
|
||||
luaunit.assertEquals(element.y, 0)
|
||||
|
||||
-- Simulate time passing (0.5 seconds)
|
||||
element:update(0.5)
|
||||
|
||||
-- Test mid-animation state (linear interpolation)
|
||||
luaunit.assertEquals(element.x, 100) -- Half way there
|
||||
luaunit.assertEquals(element.y, 75) -- Half way there
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testChainedTransformations()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Apply multiple transformations in sequence
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.translate)
|
||||
luaunit.assertNotNil(element.scale)
|
||||
luaunit.assertNotNil(element.rotate)
|
||||
element:translate(50, 50):scale(2, 2):rotate(math.pi / 2)
|
||||
|
||||
-- Verify final state
|
||||
luaunit.assertEquals(element.x, 50)
|
||||
luaunit.assertEquals(element.y, 50)
|
||||
luaunit.assertEquals(element.width, 200)
|
||||
luaunit.assertEquals(element.height, 200)
|
||||
luaunit.assertNotNil(element.rotation)
|
||||
luaunit.assertEquals(element.rotation, math.pi / 2)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testAnimationCancellation()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Start animation
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.animate)
|
||||
luaunit.assertNotNil(element.update)
|
||||
luaunit.assertNotNil(element.stopAnimation)
|
||||
element:animate({
|
||||
x = 200,
|
||||
y = 200,
|
||||
duration = 2.0,
|
||||
})
|
||||
|
||||
-- Update partially
|
||||
element:update(0.5)
|
||||
|
||||
-- Cancel animation
|
||||
element:stopAnimation()
|
||||
|
||||
-- Position should remain at last updated position
|
||||
local x = element.x
|
||||
local y = element.y
|
||||
|
||||
-- Update again to ensure animation stopped
|
||||
element:update(0.5)
|
||||
|
||||
luaunit.assertEquals(element.x, x)
|
||||
luaunit.assertEquals(element.y, y)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testMultiplePropertyAnimation()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
alpha = 1.0,
|
||||
})
|
||||
|
||||
-- Animate multiple properties simultaneously
|
||||
luaunit.assertNotNil(element)
|
||||
luaunit.assertNotNil(element.animate)
|
||||
luaunit.assertNotNil(element.update)
|
||||
element:animate({
|
||||
x = 200,
|
||||
y = 200,
|
||||
width = 200,
|
||||
height = 200,
|
||||
alpha = 0.5,
|
||||
duration = 1.0,
|
||||
easing = "linear",
|
||||
})
|
||||
|
||||
-- Update halfway
|
||||
element:update(0.5)
|
||||
|
||||
-- Test all properties at midpoint
|
||||
luaunit.assertEquals(element.x, 100)
|
||||
luaunit.assertEquals(element.y, 100)
|
||||
luaunit.assertEquals(element.width, 150)
|
||||
luaunit.assertEquals(element.height, 150)
|
||||
luaunit.assertNotNil(element.alpha)
|
||||
luaunit.assertEquals(element.alpha, 0.75)
|
||||
end
|
||||
|
||||
function TestAnimationAndTransform:testEasingFunctions()
|
||||
local element = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test different easing functions
|
||||
local easings = { "linear", "easeInQuad", "easeOutQuad", "easeInOutQuad" }
|
||||
|
||||
for _, easing in ipairs(easings) do
|
||||
element.x = 0
|
||||
luaunit.assertNotNil(element.animate)
|
||||
element:animate({
|
||||
x = 100,
|
||||
duration = 1.0,
|
||||
easing = easing,
|
||||
})
|
||||
|
||||
element:update(0.5)
|
||||
|
||||
-- Ensure animation is progressing (exact values depend on easing function)
|
||||
luaunit.assertTrue(element.x > 0 and element.x < 100)
|
||||
end
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
250
testing/__tests__/11_auxiliary_functions.lua
Normal file
250
testing/__tests__/11_auxiliary_functions.lua
Normal file
@@ -0,0 +1,250 @@
|
||||
package.path = package.path .. ";?.lua"
|
||||
|
||||
local luaunit = require("testing/luaunit")
|
||||
require("testing/loveStub") -- Required to mock LOVE functions
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
-- Create test cases
|
||||
TestAuxiliaryFunctions = {}
|
||||
|
||||
function TestAuxiliaryFunctions:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testFindElementById()
|
||||
local root = self.GUI.new({
|
||||
id = "root",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
local child = self.GUI.new({
|
||||
id = "child",
|
||||
parent = root,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test finding elements by ID
|
||||
luaunit.assertNotNil(self.GUI.findElementById)
|
||||
local foundRoot = self.GUI:findElementById("root")
|
||||
local foundChild = self.GUI:findElementById("child")
|
||||
|
||||
luaunit.assertNotNil(foundRoot)
|
||||
luaunit.assertNotNil(foundChild)
|
||||
luaunit.assertEquals(foundRoot, root)
|
||||
luaunit.assertEquals(foundChild, child)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testFindElementsByClass()
|
||||
local root = self.GUI.new({
|
||||
class = "container",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
class = "item",
|
||||
parent = root,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
class = "item",
|
||||
parent = root,
|
||||
x = 100,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test finding elements by class
|
||||
luaunit.assertNotNil(self.GUI.findElementsByClass)
|
||||
local items = self.GUI:findElementsByClass("item")
|
||||
luaunit.assertEquals(#items, 2)
|
||||
|
||||
local containers = self.GUI:findElementsByClass("container")
|
||||
luaunit.assertEquals(#containers, 1)
|
||||
luaunit.assertEquals(containers[1], root)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testGetElementsAtPoint()
|
||||
local root = self.GUI.new({
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
parent = root,
|
||||
x = 50,
|
||||
y = 50,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
parent = root,
|
||||
x = 200,
|
||||
y = 200,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test getting elements at specific points
|
||||
luaunit.assertNotNil(self.GUI.getElementsAtPoint)
|
||||
local elements1 = self.GUI:getElementsAtPoint(75, 75)
|
||||
local elements2 = self.GUI:getElementsAtPoint(250, 250)
|
||||
local elements3 = self.GUI:getElementsAtPoint(0, 0)
|
||||
|
||||
luaunit.assertTrue(#elements1 >= 2) -- Should find root and child1
|
||||
luaunit.assertTrue(#elements2 >= 2) -- Should find root and child2
|
||||
luaunit.assertEquals(#elements3, 1) -- Should only find root
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testQuerySelector()
|
||||
local root = self.GUI.new({
|
||||
id = "root",
|
||||
class = "container",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
id = "btn1",
|
||||
class = "button primary",
|
||||
parent = root,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
id = "btn2",
|
||||
class = "button secondary",
|
||||
parent = root,
|
||||
x = 100,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test querySelector functionality
|
||||
luaunit.assertNotNil(self.GUI.querySelector)
|
||||
local container = self.GUI:querySelector(".container")
|
||||
local primaryBtn = self.GUI:querySelector(".button.primary")
|
||||
local secondaryBtn = self.GUI:querySelector(".button.secondary")
|
||||
local specificBtn = self.GUI:querySelector("#btn1")
|
||||
|
||||
luaunit.assertNotNil(container)
|
||||
luaunit.assertNotNil(primaryBtn)
|
||||
luaunit.assertNotNil(secondaryBtn)
|
||||
luaunit.assertNotNil(specificBtn)
|
||||
luaunit.assertEquals(container, root)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testQuerySelectorAll()
|
||||
local root = self.GUI.new({
|
||||
class = "container",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
for i = 1, 3 do
|
||||
self.GUI.new({
|
||||
class = "item",
|
||||
parent = root,
|
||||
x = i * 100,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
end
|
||||
|
||||
-- Test querySelectorAll functionality
|
||||
luaunit.assertNotNil(self.GUI.querySelectorAll)
|
||||
local items = self.GUI:querySelectorAll(".item")
|
||||
local containers = self.GUI:querySelectorAll(".container")
|
||||
|
||||
luaunit.assertEquals(#items, 3)
|
||||
luaunit.assertEquals(#containers, 1)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testDebugPrint()
|
||||
local root = self.GUI.new({
|
||||
id = "root",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 500,
|
||||
h = 500,
|
||||
})
|
||||
|
||||
self.GUI.new({
|
||||
id = "child",
|
||||
parent = root,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 100,
|
||||
h = 100,
|
||||
})
|
||||
|
||||
-- Test debug print functionality
|
||||
luaunit.assertNotNil(self.GUI.debugPrint)
|
||||
local debugOutput = self.GUI:debugPrint()
|
||||
luaunit.assertNotNil(debugOutput)
|
||||
luaunit.assertString(debugOutput)
|
||||
luaunit.assertTrue(string.find(debugOutput, "root") ~= nil)
|
||||
luaunit.assertTrue(string.find(debugOutput, "child") ~= nil)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testMeasureText()
|
||||
local text = "Hello World"
|
||||
local fontSize = 12
|
||||
|
||||
-- Test text measurement functionality
|
||||
luaunit.assertNotNil(self.GUI.measureText)
|
||||
local width, height = self.GUI:measureText(text, fontSize)
|
||||
|
||||
luaunit.assertNotNil(width)
|
||||
luaunit.assertNotNil(height)
|
||||
luaunit.assertNumber(width)
|
||||
luaunit.assertNumber(height)
|
||||
luaunit.assertTrue(width > 0)
|
||||
luaunit.assertTrue(height > 0)
|
||||
end
|
||||
|
||||
function TestAuxiliaryFunctions:testUtilityFunctions()
|
||||
-- Test color conversion
|
||||
luaunit.assertNotNil(self.GUI.hexToRGB)
|
||||
local r, g, b = self.GUI:hexToRGB("#FF0000")
|
||||
luaunit.assertEquals(r, 255)
|
||||
luaunit.assertEquals(g, 0)
|
||||
luaunit.assertEquals(b, 0)
|
||||
|
||||
-- Test point inside rectangle
|
||||
luaunit.assertNotNil(self.GUI.pointInRect)
|
||||
local isInside = self.GUI:pointInRect(10, 10, 0, 0, 20, 20)
|
||||
luaunit.assertTrue(isInside)
|
||||
|
||||
-- Test rectangle intersection
|
||||
luaunit.assertNotNil(self.GUI.rectIntersect)
|
||||
local intersects = self.GUI:rectIntersect(0, 0, 10, 10, 5, 5, 10, 10)
|
||||
luaunit.assertTrue(intersects)
|
||||
end
|
||||
|
||||
luaunit.LuaUnit.run()
|
||||
135
testing/__tests__/README.md
Normal file
135
testing/__tests__/README.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# FlexLove GUI Library Test Suite
|
||||
|
||||
This directory contains comprehensive tests for the FlexLove GUI library. The tests cover layout behavior, property management, animations, and utility functions.
|
||||
|
||||
## Test Files
|
||||
|
||||
1. **01_absolute_positioning.lua**
|
||||
- Basic absolute positioning
|
||||
- Parent-child relationships
|
||||
- Coordinate system tests
|
||||
|
||||
2. **02_flex_direction.lua**
|
||||
- Horizontal flex layout
|
||||
- Vertical flex layout
|
||||
- Mixed direction layouts
|
||||
|
||||
3. **03_vertical_flex_direction.lua**
|
||||
- Vertical layout specifics
|
||||
- Column-based layouts
|
||||
- Vertical alignment
|
||||
|
||||
4. **04_justify_content.lua**
|
||||
- Flex-start alignment
|
||||
- Flex-end alignment
|
||||
- Space-between distribution
|
||||
- Space-around distribution
|
||||
|
||||
5. **05_align_items.lua**
|
||||
- Cross-axis alignment
|
||||
- Stretch behavior
|
||||
- Baseline alignment
|
||||
|
||||
6. **06_flex_wrap.lua**
|
||||
- Wrapping behavior
|
||||
- Multi-line layouts
|
||||
- Wrap alignment
|
||||
|
||||
7. **07_layout_validation.lua**
|
||||
- Edge cases
|
||||
- Nested containers
|
||||
- Deep hierarchies
|
||||
|
||||
8. **08_performance.lua**
|
||||
- Large element counts
|
||||
- Deep hierarchies
|
||||
- Dynamic updates
|
||||
- Rapid resizing
|
||||
|
||||
9. **09_element_properties.lua**
|
||||
- Basic properties
|
||||
- Custom properties
|
||||
- Property modification
|
||||
- Visibility and clipping
|
||||
|
||||
10. **10_animation_and_transform.lua**
|
||||
- Basic transformations
|
||||
- Animation tweening
|
||||
- Easing functions
|
||||
- Animation cancellation
|
||||
|
||||
11. **11_auxiliary_functions.lua**
|
||||
- Element queries
|
||||
- Debug utilities
|
||||
- Layout helpers
|
||||
- Utility functions
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Run All Tests
|
||||
```bash
|
||||
cd /path/to/station_alpha
|
||||
for f in game/libs/testing/__tests__/flexlove/*.lua; do lua "$f"; done
|
||||
```
|
||||
|
||||
### Run Specific Test File
|
||||
```bash
|
||||
cd /path/to/station_alpha
|
||||
lua game/libs/testing/__tests__/flexlove/[test_file].lua
|
||||
```
|
||||
|
||||
## Test Structure
|
||||
|
||||
Each test file follows this general structure:
|
||||
|
||||
```lua
|
||||
package.path = package.path .. ";/path/to/station_alpha/?.lua"
|
||||
|
||||
local luaunit = require('game/libs/testing/luaunit')
|
||||
require('game/libs/testing/loveStub')
|
||||
local FlexLove = require('game/libs/FlexLove')
|
||||
|
||||
TestClassName = {}
|
||||
|
||||
function TestClassName:setUp()
|
||||
self.GUI = FlexLove.GUI
|
||||
end
|
||||
|
||||
function TestClassName:testFeature()
|
||||
-- Test implementation
|
||||
end
|
||||
|
||||
os.exit(luaunit.LuaUnit.run())
|
||||
```
|
||||
|
||||
## Known Issues
|
||||
|
||||
1. Layout Calculations
|
||||
- Some justify-content calculations need verification
|
||||
- Align-items behavior needs adjustment
|
||||
- Flex-wrap positioning requires fixes
|
||||
|
||||
2. Missing Methods
|
||||
- Animation and transform methods not implemented
|
||||
- Some utility functions not available
|
||||
- Custom property support incomplete
|
||||
|
||||
3. Performance
|
||||
- Resize calculations may need optimization
|
||||
- Deep hierarchy performance could be improved
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new tests:
|
||||
|
||||
1. Follow the existing naming convention
|
||||
2. Add proper type annotations
|
||||
3. Include nil checks for optional features
|
||||
4. Document expected behavior
|
||||
5. Add the test to this README
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Lua 5.1+ / LuaJIT
|
||||
- LÖVE2D (for graphics features)
|
||||
- luaunit (testing framework)
|
||||
42
testing/runAll.lua
Normal file
42
testing/runAll.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
package.path = package.path .. ";./?.lua;./game/?.lua;./game/utils/?.lua;./game/components/?.lua;./game/systems/?.lua"
|
||||
|
||||
local luaunit = require("testing.luaunit")
|
||||
|
||||
-- Run all tests in the __tests__ directory
|
||||
local testFiles = {
|
||||
"testing/__tests__/01_absolute_positioning.lua",
|
||||
"testing/__tests__/02_flex_direction.lua",
|
||||
"testing/__tests__/03_vertical_flex_direction.lua",
|
||||
"testing/__tests__/04_justify_content.lua",
|
||||
"testing/__tests__/05_align_items.lua",
|
||||
"testing/__tests__/06_flex_wrap.lua",
|
||||
"testing/__tests__/07_layout_validation.lua",
|
||||
"testing/__tests__/08_performance.lua",
|
||||
"testing/__tests__/09_element_properties.lua",
|
||||
"testing/__tests__/10_animation_and_transform.lua",
|
||||
"testing/__tests__/11_auxiliary_functions.lua",
|
||||
}
|
||||
|
||||
-- testingun all tests, but don't exit on error
|
||||
local success = true
|
||||
print("========================================")
|
||||
print("Running ALL tests")
|
||||
print("========================================")
|
||||
for _, testFile in ipairs(testFiles) do
|
||||
print("========================================")
|
||||
print("Running test file: " .. testFile)
|
||||
print("========================================")
|
||||
local status, err = pcall(dofile, testFile)
|
||||
if not status then
|
||||
print("Error running test " .. testFile .. ": " .. tostring(err))
|
||||
success = false
|
||||
end
|
||||
end
|
||||
|
||||
print("========================================")
|
||||
print("All tests completed")
|
||||
print("========================================")
|
||||
|
||||
-- Run the tests and exit with appropriate code
|
||||
local result = luaunit.LuaUnit.run()
|
||||
os.exit(success and result or 1)
|
||||
Reference in New Issue
Block a user