1008 lines
23 KiB
Lua
1008 lines
23 KiB
Lua
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
|
local originalSearchers = package.searchers or package.loaders
|
|
table.insert(originalSearchers, 2, function(modname)
|
|
if modname:match("^FlexLove%.modules%.") then
|
|
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
|
return function()
|
|
return require("modules." .. moduleName)
|
|
end
|
|
end
|
|
end)
|
|
require("testing.loveStub")
|
|
local luaunit = require("testing.luaunit")
|
|
local FlexLove = require("FlexLove")
|
|
|
|
FlexLove.init()
|
|
|
|
--[[
|
|
================================================================================
|
|
KNOWN BUGS IN COMMIT 157b932 - Tests will fail until these are fixed
|
|
================================================================================
|
|
|
|
BUG #1: FLEX BASIS AUTO USES MODIFIED WIDTH
|
|
Location: LayoutEngine.lua:247-253
|
|
Problem: When flexBasis="auto", the implementation uses getBorderBoxWidth() which
|
|
returns the CURRENT width (already modified by previous layouts), not the
|
|
ORIGINAL width specified in props.
|
|
|
|
Impact: Incorrect flex calculations when layout runs multiple times
|
|
Example: child with width=100, flexGrow=1 added alone grows to 600px.
|
|
When second child added, first child's flexBasis uses 600px not 100px.
|
|
|
|
Fix: Use element.units.width to recalculate original size from stored value/unit
|
|
instead of getBorderBoxWidth()
|
|
|
|
Tests affected: Most TestFlexGrow tests will fail due to this bug
|
|
|
|
|
|
BUG #2: SHRINKING NOT TRIGGERED WITHOUT FLEXGROW
|
|
Location: LayoutEngine.lua:524-530
|
|
Problem: needsFlexSizing only checks if (flexGrow > 0 OR flexBasis != "auto")
|
|
This means items with default flexShrink=1 won't shrink in overflow
|
|
situations unless they also have flexGrow > 0 or explicit flexBasis.
|
|
|
|
Impact: Items don't shrink by default like CSS flexbox behavior
|
|
CSS default: flex-shrink: 1 (items shrink to prevent overflow)
|
|
|
|
Fix: Also check if shrinking might be needed (items overflow container)
|
|
Or always run flex sizing algorithm for flex containers
|
|
|
|
Tests affected: All TestFlexShrink tests will fail due to this bug
|
|
|
|
================================================================================
|
|
]]
|
|
|
|
-- ============================================================================
|
|
-- Helper Functions
|
|
-- ============================================================================
|
|
|
|
local function roundToDecimal(num, decimals)
|
|
local mult = 10 ^ (decimals or 2)
|
|
return math.floor(num * mult + 0.5) / mult
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 1: Flex Shorthand Parsing
|
|
-- ============================================================================
|
|
|
|
TestFlexShorthand = {}
|
|
|
|
function TestFlexShorthand:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexShorthand:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_number_shorthand()
|
|
-- flex: 1 should set flexGrow=1, flexShrink=1, flexBasis=0
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = 1,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 1)
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
luaunit.assertEquals(element.flexBasis, 0)
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_auto_shorthand()
|
|
-- flex: "auto" should set flexGrow=1, flexShrink=1, flexBasis="auto"
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = "auto",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 1)
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
luaunit.assertEquals(element.flexBasis, "auto")
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_none_shorthand()
|
|
-- flex: "none" should set flexGrow=0, flexShrink=0, flexBasis="auto"
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = "none",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 0)
|
|
luaunit.assertEquals(element.flexShrink, 0)
|
|
luaunit.assertEquals(element.flexBasis, "auto")
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_two_values_numbers()
|
|
-- flex: "2 0" should set flexGrow=2, flexShrink=0, flexBasis=0
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = "2 0",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 2)
|
|
luaunit.assertEquals(element.flexShrink, 0)
|
|
luaunit.assertEquals(element.flexBasis, 0)
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_grow_with_basis()
|
|
-- flex: "1 200px" should set flexGrow=1, flexShrink=1, flexBasis="200px"
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = "1 200px",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 1)
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
luaunit.assertEquals(element.flexBasis, "200px")
|
|
end
|
|
|
|
function TestFlexShorthand:test_flex_three_values()
|
|
-- flex: "2 1 150px" should set all three values
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = "2 1 150px",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 2)
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
luaunit.assertEquals(element.flexBasis, "150px")
|
|
end
|
|
|
|
function TestFlexShorthand:test_explicit_props_override_shorthand()
|
|
-- Explicit properties should override flex shorthand
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flex = 1,
|
|
flexGrow = 3,
|
|
flexShrink = 0,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 3)
|
|
luaunit.assertEquals(element.flexShrink, 0)
|
|
luaunit.assertEquals(element.flexBasis, 0)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 2: Flex Property Validation
|
|
-- ============================================================================
|
|
|
|
TestFlexPropertyValidation = {}
|
|
|
|
function TestFlexPropertyValidation:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexPropertyValidation:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_default_flex_values()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 0)
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
luaunit.assertEquals(element.flexBasis, "auto")
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_valid_flexGrow()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexGrow = 2,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 2)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_invalid_flexGrow_negative()
|
|
-- Negative flexGrow should default to 0 with warning
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexGrow = -1,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 0)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_invalid_flexGrow_string()
|
|
-- String flexGrow should default to 0 with warning
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexGrow = "invalid",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexGrow, 0)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_valid_flexShrink()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexShrink = 0,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexShrink, 0)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_invalid_flexShrink_negative()
|
|
-- Negative flexShrink should default to 1 with warning
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexShrink = -1,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexShrink, 1)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_flexBasis_auto()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexBasis = "auto",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexBasis, "auto")
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_flexBasis_number()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexBasis = 200,
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexBasis, 200)
|
|
end
|
|
|
|
function TestFlexPropertyValidation:test_flexBasis_with_units()
|
|
local element = FlexLove.new({
|
|
width = 100,
|
|
height = 100,
|
|
flexBasis = "50%",
|
|
})
|
|
|
|
luaunit.assertEquals(element.flexBasis, "50%")
|
|
luaunit.assertNotNil(element.units.flexBasis)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 3: Flex Grow - Distributing Extra Space
|
|
-- ============================================================================
|
|
|
|
TestFlexGrow = {}
|
|
|
|
function TestFlexGrow:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexGrow:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexGrow:test_single_item_with_flex_grow()
|
|
local container = FlexLove.new({
|
|
width = 500,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Child should grow to fill container: 500px
|
|
luaunit.assertEquals(child.width, 500)
|
|
end
|
|
|
|
function TestFlexGrow:test_two_items_equal_flex_grow()
|
|
local container = FlexLove.new({
|
|
width = 600,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Both children should grow equally: (600 - 200) / 2 = 200 extra each
|
|
luaunit.assertEquals(child1.width, 300)
|
|
luaunit.assertEquals(child2.width, 300)
|
|
end
|
|
|
|
function TestFlexGrow:test_proportional_flex_grow()
|
|
local container = FlexLove.new({
|
|
width = 700,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 2,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Free space: 700 - 200 = 500
|
|
-- child1 gets: 100 + (1/3 * 500) = 266.67
|
|
-- child2 gets: 100 + (2/3 * 500) = 433.33
|
|
luaunit.assertEquals(roundToDecimal(child1.width, 1), 266.7)
|
|
luaunit.assertEquals(roundToDecimal(child2.width, 1), 433.3)
|
|
end
|
|
|
|
function TestFlexGrow:test_flex_grow_with_gap()
|
|
local container = FlexLove.new({
|
|
width = 620,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 20,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Available space: 620 - 20(gap) = 600
|
|
-- Free space: 600 - 200 = 400, divided equally = 200 each
|
|
luaunit.assertEquals(child1.width, 300)
|
|
luaunit.assertEquals(child2.width, 300)
|
|
end
|
|
|
|
function TestFlexGrow:test_flex_grow_vertical()
|
|
local container = FlexLove.new({
|
|
width = 100,
|
|
height = 500,
|
|
positioning = "flex",
|
|
flexDirection = "vertical",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 50,
|
|
height = 100,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 50,
|
|
height = 100,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Both children should grow equally in vertical direction
|
|
luaunit.assertEquals(child1.height, 250)
|
|
luaunit.assertEquals(child2.height, 250)
|
|
end
|
|
|
|
function TestFlexGrow:test_flex_grow_with_margins()
|
|
local container = FlexLove.new({
|
|
width = 640,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
margin = { left = 10, right = 10, top = 0, bottom = 0 },
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
margin = { left = 10, right = 10, top = 0, bottom = 0 },
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Total margins: 40px (10+10 for each child)
|
|
-- Basis sizes with margins: 120 + 120 = 240
|
|
-- Free space: 640 - 240 = 400
|
|
-- Each child grows by 200, so final width = 300
|
|
luaunit.assertEquals(child1.width, 300)
|
|
luaunit.assertEquals(child2.width, 300)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 4: Flex Shrink - Handling Overflow
|
|
-- ============================================================================
|
|
|
|
TestFlexShrink = {}
|
|
|
|
function TestFlexShrink:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexShrink:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexShrink:test_items_shrink_equally()
|
|
-- CSS behavior: Items with flex-shrink: 1 (default) should shrink when overflow
|
|
local container = FlexLove.new({
|
|
width = 300,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Overflow: 400 - 300 = 100
|
|
-- Both shrink equally (same flex-shrink and flex-basis)
|
|
-- Expected CSS behavior: 150px each
|
|
luaunit.assertEquals(child1.width, 150)
|
|
luaunit.assertEquals(child2.width, 150)
|
|
end
|
|
|
|
function TestFlexShrink:test_proportional_shrink()
|
|
local container = FlexLove.new({
|
|
width = 300,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 2,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Overflow: 400 - 300 = 100
|
|
-- Scaled shrink factors: 1*200=200, 2*200=400, total=600
|
|
-- child1 shrinks: (200/600) * 100 = 33.33, final = 166.67
|
|
-- child2 shrinks: (400/600) * 100 = 66.67, final = 133.33
|
|
luaunit.assertEquals(roundToDecimal(child1.width, 1), 166.7)
|
|
luaunit.assertEquals(roundToDecimal(child2.width, 1), 133.3)
|
|
end
|
|
|
|
function TestFlexShrink:test_flex_shrink_zero_prevents_shrinking()
|
|
local container = FlexLove.new({
|
|
width = 300,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexShrink = 0,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- child1 should not shrink (flexShrink = 0)
|
|
-- child2 absorbs all overflow: 200 - 50 = 150
|
|
luaunit.assertEquals(child1.width, 150)
|
|
luaunit.assertEquals(child2.width, 150)
|
|
end
|
|
|
|
function TestFlexShrink:test_different_basis_affects_shrink()
|
|
local container = FlexLove.new({
|
|
width = 300,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 300,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Overflow: 400 - 300 = 100
|
|
-- Scaled shrink factors: 1*100=100, 1*300=300, total=400
|
|
-- child1 shrinks: (100/400) * 100 = 25, final = 75
|
|
-- child2 shrinks: (300/400) * 100 = 75, final = 225
|
|
luaunit.assertEquals(child1.width, 75)
|
|
luaunit.assertEquals(child2.width, 225)
|
|
end
|
|
|
|
function TestFlexShrink:test_shrink_with_margins()
|
|
local container = FlexLove.new({
|
|
width = 300,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
margin = { left = 10, right = 10, top = 0, bottom = 0 },
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexShrink = 1,
|
|
margin = { left = 10, right = 10, top = 0, bottom = 0 },
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Basis sizes with margins: 220 + 220 = 440
|
|
-- Overflow: 440 - 300 = 140
|
|
-- Both shrink equally: 70 each
|
|
luaunit.assertEquals(child1.width, 130)
|
|
luaunit.assertEquals(child2.width, 130)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 5: Flex Basis
|
|
-- ============================================================================
|
|
|
|
TestFlexBasis = {}
|
|
|
|
function TestFlexBasis:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexBasis:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexBasis:test_flexBasis_auto_uses_element_width()
|
|
local container = FlexLove.new({
|
|
width = 500,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexBasis = "auto",
|
|
flexGrow = 0,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- flexBasis "auto" should use element's width
|
|
luaunit.assertEquals(child.width, 150)
|
|
end
|
|
|
|
function TestFlexBasis:test_flexBasis_numeric_overrides_width()
|
|
local container = FlexLove.new({
|
|
width = 500,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexBasis = 200,
|
|
flexGrow = 0,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- flexBasis should override width as the starting point
|
|
luaunit.assertEquals(child.width, 200)
|
|
end
|
|
|
|
function TestFlexBasis:test_flexBasis_percentage()
|
|
local container = FlexLove.new({
|
|
width = 600,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexBasis = "50%",
|
|
flexGrow = 0,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- flexBasis 50% of container = 300px
|
|
luaunit.assertEquals(child.width, 300)
|
|
end
|
|
|
|
function TestFlexBasis:test_flexBasis_with_grow()
|
|
local container = FlexLove.new({
|
|
width = 600,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexBasis = 100,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexBasis = 200,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Total basis: 300, free space: 300
|
|
-- Each grows by 150
|
|
luaunit.assertEquals(child1.width, 250)
|
|
luaunit.assertEquals(child2.width, 350)
|
|
end
|
|
|
|
function TestFlexBasis:test_flexBasis_zero_with_grow()
|
|
local container = FlexLove.new({
|
|
width = 600,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexBasis = 0,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexBasis = 0,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Total basis: 0, all space is free space
|
|
-- Distributed equally: 300 each
|
|
luaunit.assertEquals(child1.width, 300)
|
|
luaunit.assertEquals(child2.width, 300)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Test Suite 6: Complex Scenarios
|
|
-- ============================================================================
|
|
|
|
TestFlexComplexScenarios = {}
|
|
|
|
function TestFlexComplexScenarios:setUp()
|
|
FlexLove.beginFrame()
|
|
end
|
|
|
|
function TestFlexComplexScenarios:tearDown()
|
|
FlexLove.endFrame()
|
|
end
|
|
|
|
function TestFlexComplexScenarios:test_mixed_grow_no_grow()
|
|
local container = FlexLove.new({
|
|
width = 700,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 0,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child3 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 2,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- child1 doesn't grow: 150
|
|
-- Free space: 700 - 450 = 250
|
|
-- child2 grows: 150 + (1/3 * 250) = 233.33
|
|
-- child3 grows: 150 + (2/3 * 250) = 316.67
|
|
luaunit.assertEquals(child1.width, 150)
|
|
luaunit.assertEquals(roundToDecimal(child2.width, 1), 233.3)
|
|
luaunit.assertEquals(roundToDecimal(child3.width, 1), 316.7)
|
|
end
|
|
|
|
function TestFlexComplexScenarios:test_wrapping_with_flex_grow()
|
|
local container = FlexLove.new({
|
|
width = 400,
|
|
height = 200,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
flexWrap = "wrap",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child3 = FlexLove.new({
|
|
width = 150,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- First line: child1, child2 (300px basis, 100px free space)
|
|
-- Each grows by 50px -> 200px each
|
|
-- Second line: child3 (150px basis, 250px free space)
|
|
-- child3 grows to fill line -> 400px
|
|
luaunit.assertEquals(child1.width, 200)
|
|
luaunit.assertEquals(child2.width, 200)
|
|
luaunit.assertEquals(child3.width, 400)
|
|
end
|
|
|
|
function TestFlexComplexScenarios:test_exact_fit_no_grow_no_shrink()
|
|
local container = FlexLove.new({
|
|
width = 400,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 200,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
flexShrink = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Perfect fit: no growing or shrinking needed
|
|
luaunit.assertEquals(child1.width, 200)
|
|
luaunit.assertEquals(child2.width, 200)
|
|
end
|
|
|
|
function TestFlexComplexScenarios:test_nested_flex_containers()
|
|
local outer = FlexLove.new({
|
|
width = 800,
|
|
height = 200,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
})
|
|
|
|
local inner = FlexLove.new({
|
|
width = 400,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
flexGrow = 1,
|
|
gap = 0,
|
|
parent = outer,
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = inner,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = inner,
|
|
})
|
|
|
|
outer:layoutChildren()
|
|
|
|
-- Inner container grows from 400 to 800
|
|
luaunit.assertEquals(inner.width, 800)
|
|
-- Children of inner should each get 400
|
|
luaunit.assertEquals(child1.width, 400)
|
|
luaunit.assertEquals(child2.width, 400)
|
|
end
|
|
|
|
function TestFlexComplexScenarios:test_flex_with_padding()
|
|
local container = FlexLove.new({
|
|
width = 600,
|
|
height = 100,
|
|
positioning = "flex",
|
|
flexDirection = "horizontal",
|
|
gap = 0,
|
|
padding = { left = 20, right = 20, top = 10, bottom = 10 },
|
|
})
|
|
|
|
local child1 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
local child2 = FlexLove.new({
|
|
width = 100,
|
|
height = 50,
|
|
flexGrow = 1,
|
|
parent = container,
|
|
})
|
|
|
|
container:layoutChildren()
|
|
|
|
-- Available space: 600 - 40 (padding) = 560
|
|
-- Free space: 560 - 200 = 360, divided equally = 180 each
|
|
luaunit.assertEquals(child1.width, 280)
|
|
luaunit.assertEquals(child2.width, 280)
|
|
end
|
|
|
|
-- Run tests only if not part of runAll.lua
|
|
if not _G.RUNNING_ALL_TESTS then
|
|
os.exit(luaunit.LuaUnit.run())
|
|
end
|