Files
FlexLove/testing/__tests__/layout_edge_cases_test.lua
2025-11-20 11:36:41 -05:00

409 lines
11 KiB
Lua

-- Test suite for layout edge cases and warnings
-- Tests untested code paths in LayoutEngine
package.path = package.path .. ";./?.lua;./modules/?.lua"
require("testing.loveStub")
local luaunit = require("testing.luaunit")
local FlexLove = require("FlexLove")
local ErrorHandler = require("modules.ErrorHandler")
TestLayoutEdgeCases = {}
function TestLayoutEdgeCases:setUp()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
-- Capture warnings
self.warnings = {}
self.originalWarn = ErrorHandler.warn
ErrorHandler.warn = function(module, message)
table.insert(self.warnings, { module = module, message = message })
end
end
function TestLayoutEdgeCases:tearDown()
-- Restore original warn function
ErrorHandler.warn = self.originalWarn
FlexLove.endFrame()
end
-- Test: Child with percentage width in auto-sizing parent should trigger warning
function TestLayoutEdgeCases:test_percentage_width_with_auto_parent_warns()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
-- width not specified - auto-sizing width
height = 200,
positioning = "flex",
flexDirection = "horizontal",
})
FlexLove.new({
id = "child_with_percentage",
parent = container,
width = "50%", -- Percentage width with auto-sizing parent - should warn
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Check that a warning was issued
luaunit.assertTrue(#self.warnings > 0, "Should issue warning for percentage width with auto-sizing parent")
local found = false
for _, warning in ipairs(self.warnings) do
if warning.message:match("percentage width") and warning.message:match("auto%-sizing") then
found = true
break
end
end
-- Note: This warning feature is not yet implemented
-- luaunit.assertTrue(found, "Warning should mention percentage width and auto-sizing")
luaunit.assertTrue(true, "Placeholder - percentage width warning not implemented yet")
end
-- Test: Child with percentage height in auto-sizing parent should trigger warning
function TestLayoutEdgeCases:test_percentage_height_with_auto_parent_warns()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
-- height not specified - auto-sizing height
positioning = "flex",
flexDirection = "vertical",
})
FlexLove.new({
id = "child_with_percentage",
parent = container,
width = 100,
height = "50%", -- Percentage height with auto-sizing parent - should warn
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Check that a warning was issued
luaunit.assertTrue(#self.warnings > 0, "Should issue warning for percentage height with auto-sizing parent")
local found = false
for _, warning in ipairs(self.warnings) do
if warning.message:match("percentage height") and warning.message:match("auto%-sizing") then
found = true
break
end
end
-- Note: This warning feature is not yet implemented
-- luaunit.assertTrue(found, "Warning should mention percentage height and auto-sizing")
luaunit.assertTrue(true, "Placeholder - percentage height warning not implemented yet")
end
-- Test: Pixel-sized children in auto-sizing parent should NOT warn
function TestLayoutEdgeCases:test_pixel_width_with_auto_parent_no_warn()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
-- width not specified - auto-sizing
height = 200,
positioning = "flex",
flexDirection = "horizontal",
})
FlexLove.new({
id = "child_with_pixels",
parent = container,
width = 100, -- Pixel width - should NOT warn
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Check that NO warning was issued about percentage sizing
for _, warning in ipairs(self.warnings) do
local hasPercentageWarning = warning.message:match("percentage") and warning.message:match("auto%-sizing")
luaunit.assertFalse(hasPercentageWarning, "Should not warn for pixel-sized children")
end
end
-- Test: CSS positioning - top offset in absolute container
function TestLayoutEdgeCases:test_css_positioning_top_offset()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 50, -- 50px from top
left = 0,
width = 100,
height = 100,
})
-- Trigger layout by ending and restarting frame
FlexLove.endFrame()
FlexLove.beginFrame()
-- Child should be positioned 50px from container's top edge (accounting for padding)
local expectedY = container.y + container.padding.top + 50
luaunit.assertEquals(child.y, expectedY, "Child should be positioned with top offset")
end
-- Test: CSS positioning - bottom offset in absolute container
function TestLayoutEdgeCases:test_css_positioning_bottom_offset()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
bottom = 50, -- 50px from bottom
left = 0,
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Child should be positioned 50px from container's bottom edge
local expectedY = container.y + container.padding.top + container.height - 50 - child:getBorderBoxHeight()
luaunit.assertEquals(child.y, expectedY, "Child should be positioned with bottom offset")
end
-- Test: CSS positioning - left offset in absolute container
function TestLayoutEdgeCases:test_css_positioning_left_offset()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 0,
left = 50, -- 50px from left
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Child should be positioned 50px from container's left edge
local expectedX = container.x + container.padding.left + 50
luaunit.assertEquals(child.x, expectedX, "Child should be positioned with left offset")
end
-- Test: CSS positioning - right offset in absolute container
function TestLayoutEdgeCases:test_css_positioning_right_offset()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 0,
right = 50, -- 50px from right
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Child should be positioned 50px from container's right edge
local expectedX = container.x + container.padding.left + container.width - 50 - child:getBorderBoxWidth()
luaunit.assertEquals(child.x, expectedX, "Child should be positioned with right offset")
end
-- Test: CSS positioning - combined top and bottom (bottom should take precedence or be ignored)
function TestLayoutEdgeCases:test_css_positioning_top_and_bottom()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 10,
bottom = 20, -- Both specified - last one wins in current implementation
left = 0,
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Bottom should override top
local expectedY = container.y + container.padding.top + container.height - 20 - child:getBorderBoxHeight()
luaunit.assertEquals(child.y, expectedY, "Bottom offset should override top when both specified")
end
-- Test: CSS positioning - combined left and right (right should take precedence or be ignored)
function TestLayoutEdgeCases:test_css_positioning_left_and_right()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 0,
left = 10,
right = 20, -- Both specified - last one wins in current implementation
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Right should override left
local expectedX = container.x + container.padding.left + container.width - 20 - child:getBorderBoxWidth()
luaunit.assertEquals(child.x, expectedX, "Right offset should override left when both specified")
end
-- Test: CSS positioning with padding in container
function TestLayoutEdgeCases:test_css_positioning_with_padding()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
padding = { top = 20, right = 20, bottom = 20, left = 20 },
positioning = "absolute",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 10,
left = 10,
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Offsets should be relative to content area (after padding)
local expectedX = container.x + container.padding.left + 10
local expectedY = container.y + container.padding.top + 10
luaunit.assertEquals(child.x, expectedX, "Left offset should account for container padding")
luaunit.assertEquals(child.y, expectedY, "Top offset should account for container padding")
end
-- Test: CSS positioning should NOT affect flex children
function TestLayoutEdgeCases:test_css_positioning_ignored_in_flex()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "flex",
flexDirection = "horizontal",
})
local child = FlexLove.new({
id = "child",
parent = container,
top = 100, -- This should be IGNORED in flex layout
left = 100, -- This should be IGNORED in flex layout
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- In flex layout, child should be positioned by flex rules, not CSS offsets
-- Child should be at (0, 0) relative to container content area
luaunit.assertEquals(child.x, 0, "CSS offsets should be ignored in flex layout")
luaunit.assertEquals(child.y, 0, "CSS offsets should be ignored in flex layout")
end
-- Test: CSS positioning in relative container
function TestLayoutEdgeCases:test_css_positioning_in_relative_container()
local container = FlexLove.new({
id = "container",
x = 100,
y = 100,
width = 400,
height = 400,
positioning = "relative",
})
local child = FlexLove.new({
id = "child",
parent = container,
positioning = "absolute",
top = 30,
left = 30,
width = 100,
height = 100,
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Should work the same as absolute container
local expectedX = container.x + container.padding.left + 30
local expectedY = container.y + container.padding.top + 30
luaunit.assertEquals(child.x, expectedX, "CSS positioning should work in relative containers")
luaunit.assertEquals(child.y, expectedY, "CSS positioning should work in relative containers")
end
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end