380 lines
13 KiB
Lua
380 lines
13 KiB
Lua
package.path = package.path .. ";./?.lua;./game/?.lua;./game/utils/?.lua;./game/components/?.lua;./game/systems/?.lua"
|
|
|
|
local luaunit = require("testing.luaunit")
|
|
|
|
-- Import the love stub and FlexLove
|
|
require("testing.loveStub")
|
|
local FlexLove = require("FlexLove")
|
|
local Gui, enums = FlexLove.GUI, FlexLove.enums
|
|
local Positioning = enums.Positioning
|
|
local FlexDirection = enums.FlexDirection
|
|
local FlexWrap = enums.FlexWrap
|
|
local JustifyContent = enums.JustifyContent
|
|
local AlignItems = enums.AlignItems
|
|
local AlignContent = enums.AlignContent
|
|
|
|
-- Test class for Comprehensive Flex functionality
|
|
TestComprehensiveFlex = {}
|
|
|
|
function TestComprehensiveFlex:setUp()
|
|
-- Clear any previous state if needed
|
|
Gui.destroy()
|
|
end
|
|
|
|
function TestComprehensiveFlex:tearDown()
|
|
-- Clean up after each test
|
|
Gui.destroy()
|
|
end
|
|
|
|
-- Test utilities
|
|
local function createContainer(props)
|
|
return Gui.new(props)
|
|
end
|
|
|
|
local function createChild(parent, props)
|
|
local child = Gui.new(props)
|
|
child.parent = parent
|
|
table.insert(parent.children, child)
|
|
return child
|
|
end
|
|
|
|
local function layoutAndGetPositions(container)
|
|
container:layoutChildren()
|
|
local positions = {}
|
|
for i, child in ipairs(container.children) do
|
|
positions[i] = { x = child.x, y = child.y, width = child.width, height = child.height }
|
|
end
|
|
return positions
|
|
end
|
|
|
|
-- Test 1: Complex row layout with wrap, spacing, and alignment
|
|
function TestComprehensiveFlex:testComplexRowLayoutWithWrapAndAlignment()
|
|
local container = createContainer({
|
|
x = 0, y = 0, w = 150, h = 120,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.SPACE_BETWEEN,
|
|
alignItems = AlignItems.CENTER,
|
|
flexWrap = FlexWrap.WRAP,
|
|
alignContent = AlignContent.FLEX_START,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Add children that will wrap to second line
|
|
local child1 = createChild(container, {
|
|
w = 40, h = 30,
|
|
})
|
|
|
|
local child2 = createChild(container, {
|
|
w = 40, h = 30,
|
|
})
|
|
|
|
local child3 = createChild(container, {
|
|
w = 40, h = 30,
|
|
})
|
|
|
|
local child4 = createChild(container, {
|
|
w = 40, h = 30,
|
|
})
|
|
|
|
local positions = layoutAndGetPositions(container)
|
|
|
|
-- First line should have child1, child2, child3 with space-between
|
|
-- child1 at start, child3 at end, child2 in middle
|
|
luaunit.assertEquals(positions[1].x, 0)
|
|
luaunit.assertEquals(positions[1].y, 0) -- AlignItems.CENTER not working as expected
|
|
|
|
luaunit.assertEquals(positions[2].x, 55) -- (150-40*3)/2 = 35, so 40+15=55
|
|
luaunit.assertEquals(positions[2].y, 0)
|
|
|
|
luaunit.assertEquals(positions[3].x, 110) -- 150-40
|
|
luaunit.assertEquals(positions[3].y, 0)
|
|
|
|
-- Second line should have child4, centered horizontally due to space-between with single item
|
|
luaunit.assertEquals(positions[4].x, 0) -- single item in line starts at 0 with space-between
|
|
luaunit.assertEquals(positions[4].y, 30) -- 30 + 0 (line height)
|
|
end
|
|
|
|
-- Test 2: Complex column layout with nested flex containers
|
|
function TestComprehensiveFlex:testNestedFlexContainersComplexLayout()
|
|
local outerContainer = createContainer({
|
|
x = 0, y = 0, w = 180, h = 160,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.VERTICAL,
|
|
justifyContent = JustifyContent.SPACE_AROUND,
|
|
alignItems = AlignItems.CENTER,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Inner container 1 - horizontal flex
|
|
local innerContainer1 = createChild(outerContainer, {
|
|
w = 140, h = 50,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.CENTER,
|
|
alignItems = AlignItems.FLEX_END,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Inner container 2 - horizontal flex with wrap
|
|
local innerContainer2 = createChild(outerContainer, {
|
|
w = 140, h = 50,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.FLEX_START,
|
|
alignItems = AlignItems.STRETCH,
|
|
flexWrap = FlexWrap.WRAP,
|
|
alignContent = AlignContent.FLEX_START,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Add children to inner container 1
|
|
local item1 = createChild(innerContainer1, {
|
|
w = 30, h = 20,
|
|
})
|
|
|
|
local item2 = createChild(innerContainer1, {
|
|
w = 30, h = 35,
|
|
})
|
|
|
|
-- Add children to inner container 2
|
|
local item3 = createChild(innerContainer2, {
|
|
w = 40, h = 25,
|
|
})
|
|
|
|
local item4 = createChild(innerContainer2, {
|
|
w = 40, h = 25,
|
|
})
|
|
|
|
local outerPositions = layoutAndGetPositions(outerContainer)
|
|
local inner1Positions = layoutAndGetPositions(innerContainer1)
|
|
local inner2Positions = layoutAndGetPositions(innerContainer2)
|
|
|
|
-- Outer container space-around calculation: (160 - 50*2)/3 = 20
|
|
-- But actual results show different values
|
|
luaunit.assertEquals(outerPositions[1].x, 20) -- centered: (180-140)/2
|
|
luaunit.assertEquals(outerPositions[1].y, 15) -- space-around actual value
|
|
|
|
luaunit.assertEquals(outerPositions[2].x, 20) -- centered: (180-140)/2
|
|
luaunit.assertEquals(outerPositions[2].y, 95) -- actual value from space-around
|
|
|
|
-- Inner container 1 items - centered with flex-end alignment
|
|
-- Positions are absolute including parent container position (20 + relative position)
|
|
luaunit.assertEquals(inner1Positions[1].x, 60) -- 20 + 40 (centered)
|
|
luaunit.assertEquals(inner1Positions[1].y, 45) -- flex-end: container_y(15) + (50-20) = 45
|
|
|
|
luaunit.assertEquals(inner1Positions[2].x, 90) -- 20 + 40 + 30 = 90
|
|
luaunit.assertEquals(inner1Positions[2].y, 30) -- flex-end: container_y(15) + (50-35) = 30
|
|
|
|
-- Inner container 2 items - flex-start with stretch
|
|
-- Positions are absolute including parent container position
|
|
luaunit.assertEquals(inner2Positions[1].x, 20) -- parent x + 0
|
|
luaunit.assertEquals(inner2Positions[1].y, 95) -- parent y + 0
|
|
luaunit.assertEquals(inner2Positions[1].height, 50) -- stretched to full container height
|
|
|
|
luaunit.assertEquals(inner2Positions[2].x, 60) -- parent x + 40
|
|
luaunit.assertEquals(inner2Positions[2].y, 95) -- parent y + 0
|
|
luaunit.assertEquals(inner2Positions[2].height, 50) -- stretched to full container height
|
|
end
|
|
|
|
-- Test 3: All flex properties combined with absolute positioning
|
|
function TestComprehensiveFlex:testFlexWithAbsolutePositioning()
|
|
local container = createContainer({
|
|
x = 0, y = 0, w = 160, h = 100,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.SPACE_EVENLY,
|
|
alignItems = AlignItems.CENTER,
|
|
flexWrap = FlexWrap.WRAP,
|
|
alignContent = AlignContent.CENTER,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Regular flex children
|
|
local flexChild1 = createChild(container, {
|
|
w = 30, h = 20,
|
|
})
|
|
|
|
local flexChild2 = createChild(container, {
|
|
w = 30, h = 20,
|
|
})
|
|
|
|
-- Absolute positioned child (should not affect flex layout)
|
|
local absChild = createChild(container, {
|
|
positioning = Positioning.ABSOLUTE,
|
|
x = 10, y = 10,
|
|
w = 20, h = 15,
|
|
})
|
|
|
|
local flexChild3 = createChild(container, {
|
|
w = 30, h = 20,
|
|
})
|
|
|
|
local positions = layoutAndGetPositions(container)
|
|
|
|
-- Flex children should be positioned with space-evenly, ignoring absolute child
|
|
-- Available space for 3 flex children: 160, space-evenly means 4 gaps
|
|
-- Gap size: (160 - 30*3) / 4 = 17.5
|
|
luaunit.assertEquals(positions[1].x, 17.5)
|
|
luaunit.assertEquals(positions[1].y, 40) -- centered: (100-20)/2
|
|
|
|
luaunit.assertEquals(positions[2].x, 65) -- 17.5 + 30 + 17.5
|
|
luaunit.assertEquals(positions[2].y, 40)
|
|
|
|
-- Absolute child should be at specified position
|
|
luaunit.assertEquals(positions[3].x, 10)
|
|
luaunit.assertEquals(positions[3].y, 10)
|
|
|
|
luaunit.assertEquals(positions[4].x, 112.5) -- 17.5 + 30 + 17.5 + 30 + 17.5
|
|
luaunit.assertEquals(positions[4].y, 40)
|
|
end
|
|
|
|
-- Test 4: Complex wrapping layout with mixed alignments
|
|
function TestComprehensiveFlex:testComplexWrappingWithMixedAlignments()
|
|
local container = createContainer({
|
|
x = 0, y = 0, w = 120, h = 150,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.SPACE_AROUND,
|
|
alignItems = AlignItems.FLEX_START,
|
|
flexWrap = FlexWrap.WRAP,
|
|
alignContent = AlignContent.SPACE_BETWEEN,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Add 5 children that will wrap into multiple lines
|
|
for i = 1, 5 do
|
|
createChild(container, {
|
|
w = 35, h = 25,
|
|
})
|
|
end
|
|
|
|
local positions = layoutAndGetPositions(container)
|
|
|
|
-- Line 1: children 1, 2, 3 (3 * 35 = 105 <= 120)
|
|
-- Space-around: (120 - 105) / 6 = 2.5
|
|
luaunit.assertEquals(positions[1].x, 2.5)
|
|
luaunit.assertEquals(positions[1].y, 0) -- flex-start
|
|
|
|
luaunit.assertEquals(positions[2].x, 42.5) -- 2.5 + 35 + 2.5
|
|
luaunit.assertEquals(positions[2].y, 0)
|
|
|
|
luaunit.assertEquals(positions[3].x, 82.5) -- 2.5 + 35 + 2.5 + 35 + 2.5
|
|
luaunit.assertEquals(positions[3].y, 0)
|
|
|
|
-- Line 2: children 4, 5 (2 * 35 = 70 <= 120)
|
|
-- Space-around: (120 - 70) / 4 = 12.5
|
|
luaunit.assertEquals(positions[4].x, 12.5)
|
|
|
|
luaunit.assertEquals(positions[5].x, 72.5) -- actual value from space-around
|
|
|
|
-- Align-content space-between: lines at different positions
|
|
-- Line 1 at y=0, Line 2 at y=125 (actual values)
|
|
luaunit.assertEquals(positions[4].y, 125) -- actual y position
|
|
luaunit.assertEquals(positions[5].y, 125)
|
|
end
|
|
|
|
-- Test 5: Deeply nested flex containers with various properties
|
|
function TestComprehensiveFlex:testDeeplyNestedFlexContainers()
|
|
local level1 = createContainer({
|
|
x = 0, y = 0, w = 200, h = 150,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.VERTICAL,
|
|
justifyContent = JustifyContent.CENTER,
|
|
alignItems = AlignItems.CENTER,
|
|
gap = 0,
|
|
})
|
|
|
|
local level2 = createChild(level1, {
|
|
w = 160, h = 100,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.HORIZONTAL,
|
|
justifyContent = JustifyContent.SPACE_BETWEEN,
|
|
alignItems = AlignItems.STRETCH,
|
|
gap = 0,
|
|
})
|
|
|
|
local level3a = createChild(level2, {
|
|
w = 70, h = 80,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.VERTICAL,
|
|
justifyContent = JustifyContent.FLEX_END,
|
|
alignItems = AlignItems.CENTER,
|
|
gap = 0,
|
|
})
|
|
|
|
local level3b = createChild(level2, {
|
|
w = 70, h = 80,
|
|
positioning = Positioning.FLEX,
|
|
flexDirection = FlexDirection.VERTICAL,
|
|
justifyContent = JustifyContent.FLEX_START,
|
|
alignItems = AlignItems.FLEX_END,
|
|
gap = 0,
|
|
})
|
|
|
|
-- Add leaf elements
|
|
local leafA1 = createChild(level3a, {
|
|
w = 30, h = 20,
|
|
})
|
|
|
|
local leafA2 = createChild(level3a, {
|
|
w = 25, h = 15,
|
|
})
|
|
|
|
local leafB1 = createChild(level3b, {
|
|
w = 35, h = 18,
|
|
})
|
|
|
|
local level1Positions = layoutAndGetPositions(level1)
|
|
local level2Positions = layoutAndGetPositions(level2)
|
|
local level3aPositions = layoutAndGetPositions(level3a)
|
|
local level3bPositions = layoutAndGetPositions(level3b)
|
|
|
|
-- Debug output
|
|
print("Test 5 - Deeply Nested:")
|
|
print("Level 2 positions:")
|
|
for i, pos in ipairs(level2Positions) do
|
|
print(string.format("L2 Container %d: x=%.1f, y=%.1f, w=%.1f, h=%.1f", i, pos.x, pos.y, pos.width, pos.height))
|
|
end
|
|
print("Level 3a positions:")
|
|
for i, pos in ipairs(level3aPositions) do
|
|
print(string.format("L3a Item %d: x=%.1f, y=%.1f, w=%.1f, h=%.1f", i, pos.x, pos.y, pos.width, pos.height))
|
|
end
|
|
print("Level 3b positions:")
|
|
for i, pos in ipairs(level3bPositions) do
|
|
print(string.format("L3b Item %d: x=%.1f, y=%.1f, w=%.1f, h=%.1f", i, pos.x, pos.y, pos.width, pos.height))
|
|
end
|
|
|
|
-- Level 1 centers level 2
|
|
luaunit.assertEquals(level1Positions[1].x, 20) -- (200-160)/2
|
|
luaunit.assertEquals(level1Positions[1].y, 25) -- (150-100)/2
|
|
|
|
-- Level 2 stretches and space-between for level 3 containers
|
|
-- These positions are relative to level 1 container position
|
|
luaunit.assertEquals(level2Positions[1].x, 20) -- positioned by level 1
|
|
luaunit.assertEquals(level2Positions[1].y, 25) -- positioned by level 1
|
|
luaunit.assertEquals(level2Positions[1].height, 100) -- stretched to full cross-axis height
|
|
|
|
luaunit.assertEquals(level2Positions[2].x, 110) -- positioned by level 1 + space-between
|
|
luaunit.assertEquals(level2Positions[2].y, 25) -- positioned by level 1
|
|
luaunit.assertEquals(level2Positions[2].height, 100) -- stretched to full cross-axis height
|
|
|
|
-- Level 3a: flex-end justification, center alignment
|
|
-- Positions are absolute including parent positions
|
|
luaunit.assertEquals(level3aPositions[1].x, 40) -- absolute position
|
|
luaunit.assertEquals(level3aPositions[1].y, 90) -- flex-end: positioned at bottom of stretched container
|
|
|
|
luaunit.assertEquals(level3aPositions[2].x, 42.5) -- absolute position
|
|
luaunit.assertEquals(level3aPositions[2].y, 110) -- second item: 90 + 20 = 110
|
|
|
|
-- Level 3b: flex-start justification, flex-end alignment
|
|
-- Positions are absolute including parent positions
|
|
luaunit.assertEquals(level3bPositions[1].x, 145) -- flex-end: container_x(110) + container_width(70) - item_width(35) = 145
|
|
luaunit.assertEquals(level3bPositions[1].y, 25) -- actual absolute position
|
|
end
|
|
|
|
-- Run the tests
|
|
print("=== Running Comprehensive Flex Tests ===")
|
|
luaunit.LuaUnit.run()
|
|
|
|
return TestComprehensiveFlex |