continuing testing

This commit is contained in:
Michael Freno
2025-11-15 00:01:45 -05:00
parent 0e19188a0b
commit f8fddb7ffa
8 changed files with 1293 additions and 12 deletions

View File

@@ -0,0 +1,490 @@
-- Test suite for Grid layout functionality
-- Grid layout has 0% test coverage despite being integrated into the system
package.path = package.path .. ";./?.lua;./modules/?.lua"
require("testing.loveStub")
local luaunit = require("testing.luaunit")
local FlexLove = require("FlexLove")
TestGridLayout = {}
function TestGridLayout:setUp()
FlexLove.beginFrame(1920, 1080)
end
function TestGridLayout:tearDown()
FlexLove.endFrame()
end
-- Test basic grid layout with default 1x1 grid
function TestGridLayout:test_default_grid_single_child()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 300,
positioning = "grid"
-- Default: gridRows=1, gridColumns=1
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 50, -- Will be stretched by grid
height = 50
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Child should be stretched to fill the entire grid cell
luaunit.assertEquals(child.x, 0, "Child should be at x=0")
luaunit.assertEquals(child.y, 0, "Child should be at y=0")
luaunit.assertEquals(child.width, 400, "Child should be stretched to container width")
luaunit.assertEquals(child.height, 300, "Child should be stretched to container height")
end
-- Test 2x2 grid layout
function TestGridLayout:test_2x2_grid_four_children()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
local children = {}
for i = 1, 4 do
children[i] = FlexLove.new({
id = "child" .. i,
parent = container,
width = 50,
height = 50
})
end
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Each cell should be 200x200
-- Child 1: top-left (0, 0)
luaunit.assertEquals(children[1].x, 0, "Child 1 should be at x=0")
luaunit.assertEquals(children[1].y, 0, "Child 1 should be at y=0")
luaunit.assertEquals(children[1].width, 200, "Cell width should be 200")
luaunit.assertEquals(children[1].height, 200, "Cell height should be 200")
-- Child 2: top-right (200, 0)
luaunit.assertEquals(children[2].x, 200, "Child 2 should be at x=200")
luaunit.assertEquals(children[2].y, 0, "Child 2 should be at y=0")
-- Child 3: bottom-left (0, 200)
luaunit.assertEquals(children[3].x, 0, "Child 3 should be at x=0")
luaunit.assertEquals(children[3].y, 200, "Child 3 should be at y=200")
-- Child 4: bottom-right (200, 200)
luaunit.assertEquals(children[4].x, 200, "Child 4 should be at x=200")
luaunit.assertEquals(children[4].y, 200, "Child 4 should be at y=200")
end
-- Test grid with column and row gaps
function TestGridLayout:test_grid_with_gaps()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 420, -- 2 cells * 200 + 1 gap * 20
height = 320, -- 2 cells * 150 + 1 gap * 20
positioning = "grid",
gridRows = 2,
gridColumns = 2,
columnGap = 20,
rowGap = 20
})
local children = {}
for i = 1, 4 do
children[i] = FlexLove.new({
id = "child" .. i,
parent = container,
width = 50,
height = 50
})
end
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Cell size: (420 - 20) / 2 = 200, (320 - 20) / 2 = 150
luaunit.assertEquals(children[1].width, 200, "Cell width should be 200")
luaunit.assertEquals(children[1].height, 150, "Cell height should be 150")
-- Child 2 should be offset by cell width + gap
luaunit.assertEquals(children[2].x, 220, "Child 2 x = 200 + 20 gap")
luaunit.assertEquals(children[2].y, 0, "Child 2 should be at y=0")
-- Child 3 should be offset by cell height + gap
luaunit.assertEquals(children[3].x, 0, "Child 3 should be at x=0")
luaunit.assertEquals(children[3].y, 170, "Child 3 y = 150 + 20 gap")
end
-- Test grid with more children than cells (overflow)
function TestGridLayout:test_grid_overflow_children()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 200,
positioning = "grid",
gridRows = 2,
gridColumns = 2
-- Only 4 cells available
})
local children = {}
for i = 1, 6 do -- 6 children, but only 4 cells
children[i] = FlexLove.new({
id = "child" .. i,
parent = container,
width = 50,
height = 50
})
end
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- First 4 children should be positioned
luaunit.assertNotNil(children[1].x, "Child 1 should be positioned")
luaunit.assertNotNil(children[4].x, "Child 4 should be positioned")
-- Children 5 and 6 should NOT be positioned (or positioned at 0,0 by default)
-- This tests the overflow behavior: row >= rows breaks the loop
end
-- Test grid with alignItems center
function TestGridLayout:test_grid_align_center()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2,
alignItems = "center"
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 100,
height = 100
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Cell is 200x200, child is 100x100, should be centered
-- Center position: (200 - 100) / 2 = 50
luaunit.assertEquals(child.x, 50, "Child should be centered horizontally in cell")
luaunit.assertEquals(child.y, 50, "Child should be centered vertically in cell")
luaunit.assertEquals(child.width, 100, "Child width should not be stretched")
luaunit.assertEquals(child.height, 100, "Child height should not be stretched")
end
-- Test grid with alignItems flex-start
function TestGridLayout:test_grid_align_flex_start()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2,
alignItems = "flex-start"
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 100,
height = 100
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Child should be at top-left of cell
luaunit.assertEquals(child.x, 0, "Child should be at left of cell")
luaunit.assertEquals(child.y, 0, "Child should be at top of cell")
luaunit.assertEquals(child.width, 100, "Child width should not be stretched")
luaunit.assertEquals(child.height, 100, "Child height should not be stretched")
end
-- Test grid with alignItems flex-end
function TestGridLayout:test_grid_align_flex_end()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2,
alignItems = "flex-end"
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 100,
height = 100
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Cell is 200x200, child is 100x100, should be at bottom-right
luaunit.assertEquals(child.x, 100, "Child should be at right of cell (200 - 100)")
luaunit.assertEquals(child.y, 100, "Child should be at bottom of cell (200 - 100)")
luaunit.assertEquals(child.width, 100, "Child width should not be stretched")
luaunit.assertEquals(child.height, 100, "Child height should not be stretched")
end
-- Test grid with padding
function TestGridLayout:test_grid_with_padding()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 500, -- Total width
height = 500,
padding = { top = 50, right = 50, bottom = 50, left = 50 },
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 50,
height = 50
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Available space: 500 - 50 - 50 = 400
-- Cell size: 400 / 2 = 200
-- Child should be positioned at padding.left, padding.top
luaunit.assertEquals(child.x, 50, "Child x should account for left padding")
luaunit.assertEquals(child.y, 50, "Child y should account for top padding")
luaunit.assertEquals(child.width, 200, "Cell width should be 200")
luaunit.assertEquals(child.height, 200, "Cell height should be 200")
end
-- Test grid with absolutely positioned child (should be skipped in grid layout)
function TestGridLayout:test_grid_with_absolute_child()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
-- Regular child
local child1 = FlexLove.new({
id = "child1",
parent = container,
width = 50,
height = 50
})
-- Absolutely positioned child (should be ignored by grid layout)
local child2 = FlexLove.new({
id = "child2",
parent = container,
positioning = "absolute",
x = 10,
y = 10,
width = 30,
height = 30
})
-- Another regular child
local child3 = FlexLove.new({
id = "child3",
parent = container,
width = 50,
height = 50
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- child1 should be in first grid cell (0, 0)
luaunit.assertEquals(child1.x, 0, "Child 1 should be at x=0")
luaunit.assertEquals(child1.y, 0, "Child 1 should be at y=0")
-- child2 should keep its absolute position
luaunit.assertEquals(child2.x, 10, "Absolute child should keep x=10")
luaunit.assertEquals(child2.y, 10, "Absolute child should keep y=10")
-- child3 should be in second grid cell (200, 0), not third
luaunit.assertEquals(child3.x, 200, "Child 3 should be in second cell at x=200")
luaunit.assertEquals(child3.y, 0, "Child 3 should be in second cell at y=0")
end
-- Test edge case: empty grid
function TestGridLayout:test_empty_grid()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2
-- No children
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Should not crash
luaunit.assertEquals(#container.children, 0, "Grid should have no children")
end
-- Test edge case: grid with 0 columns or rows
function TestGridLayout:test_grid_zero_dimensions()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 0, -- Invalid: 0 rows
gridColumns = 0 -- Invalid: 0 columns
})
local child = FlexLove.new({
id = "child1",
parent = container,
width = 50,
height = 50
})
-- This might cause division by zero or other errors
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Test passes if it doesn't crash
luaunit.assertTrue(true, "Grid with 0 dimensions should not crash")
end
-- Test nested grids
function TestGridLayout:test_nested_grids()
local outerGrid = FlexLove.new({
id = "outer",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
-- First cell contains another grid
local innerGrid = FlexLove.new({
id = "inner",
parent = outerGrid,
width = 200,
height = 200,
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
-- Add children to inner grid
for i = 1, 4 do
FlexLove.new({
id = "inner_child" .. i,
parent = innerGrid,
width = 25,
height = 25
})
end
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Inner grid should be positioned in first cell of outer grid
luaunit.assertEquals(innerGrid.x, 0, "Inner grid should be at x=0")
luaunit.assertEquals(innerGrid.y, 0, "Inner grid should be at y=0")
luaunit.assertEquals(#innerGrid.children, 4, "Inner grid should have 4 children")
end
-- Test grid with reserved space from absolute children
function TestGridLayout:test_grid_with_reserved_space()
local container = FlexLove.new({
id = "grid",
x = 0,
y = 0,
width = 400,
height = 400,
positioning = "grid",
gridRows = 2,
gridColumns = 2
})
-- Absolute child with left positioning (reserves left space)
FlexLove.new({
id = "absolute_left",
parent = container,
positioning = "absolute",
left = 0,
top = 0,
width = 50,
height = 50
})
-- Regular grid child
local child1 = FlexLove.new({
id = "child1",
parent = container,
width = 50,
height = 50
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Grid should account for reserved space
-- Available width: 400 - 50 (reserved left) = 350
-- Cell width: 350 / 2 = 175
-- Child should start at x = reserved left = 50
luaunit.assertEquals(child1.x, 50, "Child should be offset by reserved left space")
luaunit.assertEquals(child1.width, 175, "Cell width should account for reserved space")
end
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end

View File

@@ -0,0 +1,404 @@
-- 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
luaunit.assertTrue(found, "Warning should mention percentage width and auto-sizing")
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
luaunit.assertTrue(found, "Warning should mention percentage height and auto-sizing")
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

View File

@@ -0,0 +1,345 @@
-- Test suite for overflow detection and scroll behavior
-- This tests the critical ScrollManager.detectOverflow() path which is currently 0% covered
package.path = package.path .. ";./?.lua;./modules/?.lua"
require("testing.loveStub")
local luaunit = require("testing.luaunit")
local FlexLove = require("FlexLove")
TestOverflowDetection = {}
function TestOverflowDetection:setUp()
FlexLove.beginFrame(1920, 1080)
end
function TestOverflowDetection:tearDown()
FlexLove.endFrame()
end
-- Test basic overflow detection when content exceeds container
function TestOverflowDetection:test_vertical_overflow_detected()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 100,
overflow = "scroll"
})
-- Add child that exceeds container height
FlexLove.new({
id = "tall_child",
parent = container,
x = 0,
y = 0,
width = 100,
height = 200 -- Taller than container (100)
})
-- Force layout to trigger detectOverflow
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Check if overflow was detected
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollY > 0, "Should detect vertical overflow")
luaunit.assertEquals(maxScrollX, 0, "Should not have horizontal overflow")
end
function TestOverflowDetection:test_horizontal_overflow_detected()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 100,
height = 200,
overflow = "scroll"
})
-- Add child that exceeds container width
FlexLove.new({
id = "wide_child",
parent = container,
x = 0,
y = 0,
width = 300, -- Wider than container (100)
height = 50
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollX > 0, "Should detect horizontal overflow")
luaunit.assertEquals(maxScrollY, 0, "Should not have vertical overflow")
end
function TestOverflowDetection:test_both_axes_overflow()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 100,
height = 100,
overflow = "scroll"
})
-- Add child that exceeds both dimensions
FlexLove.new({
id = "large_child",
parent = container,
x = 0,
y = 0,
width = 200,
height = 200
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollX > 0, "Should detect horizontal overflow")
luaunit.assertTrue(maxScrollY > 0, "Should detect vertical overflow")
end
function TestOverflowDetection:test_no_overflow_when_content_fits()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
overflow = "scroll"
})
-- Add child that fits within container
FlexLove.new({
id = "small_child",
parent = container,
x = 0,
y = 0,
width = 100,
height = 100
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertEquals(maxScrollX, 0, "Should not have horizontal overflow")
luaunit.assertEquals(maxScrollY, 0, "Should not have vertical overflow")
end
function TestOverflowDetection:test_overflow_with_multiple_children()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
overflow = "scroll",
positioning = "flex",
flexDirection = "vertical"
})
-- Add multiple children that together exceed container
for i = 1, 5 do
FlexLove.new({
id = "child_" .. i,
parent = container,
width = 150,
height = 60 -- 5 * 60 = 300, exceeds container height of 200
})
end
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollY > 0, "Should detect overflow from multiple children")
end
function TestOverflowDetection:test_overflow_with_padding()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
padding = { top = 10, right = 10, bottom = 10, left = 10 },
overflow = "scroll"
})
-- Child that fits in container but exceeds available content area (200 - 20 = 180)
FlexLove.new({
id = "child",
parent = container,
x = 0,
y = 0,
width = 190, -- Exceeds content width (180)
height = 100
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollX > 0, "Should detect overflow accounting for padding")
end
function TestOverflowDetection:test_overflow_with_margins()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
positioning = "flex",
flexDirection = "horizontal",
overflow = "scroll"
})
-- Child with margins that contribute to overflow
-- In flex layout, margins are properly accounted for in positioning
FlexLove.new({
id = "child",
parent = container,
width = 180,
height = 180,
margin = { top = 5, right = 20, bottom = 5, left = 5 } -- Total width: 5+180+20=205, overflows 200px container
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertTrue(maxScrollX > 0, "Should include child margins in overflow calculation")
end
-- Test edge case: overflow = "visible" should skip detection
function TestOverflowDetection:test_visible_overflow_skips_detection()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 100,
height = 100,
overflow = "visible" -- Should not clip or calculate overflow
})
-- Add oversized child
FlexLove.new({
id = "large_child",
parent = container,
x = 0,
y = 0,
width = 300,
height = 300
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- With overflow="visible", maxScroll should be 0 (no scrolling)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertEquals(maxScrollX, 0, "visible overflow should not enable scrolling")
luaunit.assertEquals(maxScrollY, 0, "visible overflow should not enable scrolling")
end
-- Test edge case: empty container
function TestOverflowDetection:test_empty_container_no_overflow()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
overflow = "scroll"
-- No children
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertEquals(maxScrollX, 0, "Empty container should have no overflow")
luaunit.assertEquals(maxScrollY, 0, "Empty container should have no overflow")
end
-- Test overflow with absolutely positioned children (should be ignored)
function TestOverflowDetection:test_absolute_children_ignored_in_overflow()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 200,
height = 200,
overflow = "scroll"
})
-- Regular child that fits
FlexLove.new({
id = "normal_child",
parent = container,
x = 0,
y = 0,
width = 150,
height = 150
})
-- Absolutely positioned child that extends beyond (should NOT cause overflow)
FlexLove.new({
id = "absolute_child",
parent = container,
positioning = "absolute",
top = 0,
left = 0,
width = 400,
height = 400
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
local maxScrollX, maxScrollY = container:getMaxScroll()
-- Should not have overflow because absolute children are ignored
luaunit.assertEquals(maxScrollX, 0, "Absolute children should not cause overflow")
luaunit.assertEquals(maxScrollY, 0, "Absolute children should not cause overflow")
end
-- Test scroll clamping with overflow
function TestOverflowDetection:test_scroll_clamped_to_max()
local container = FlexLove.new({
id = "container",
x = 0,
y = 0,
width = 100,
height = 100,
overflow = "scroll"
})
FlexLove.new({
id = "child",
parent = container,
x = 0,
y = 0,
width = 100,
height = 300 -- Creates 200px of vertical overflow
})
FlexLove.endFrame()
FlexLove.beginFrame(1920, 1080)
-- Try to scroll beyond max
container:setScrollPosition(0, 999999)
local scrollX, scrollY = container:getScrollPosition()
local maxScrollX, maxScrollY = container:getMaxScroll()
luaunit.assertEquals(scrollY, maxScrollY, "Scroll should be clamped to maximum")
luaunit.assertTrue(scrollY < 999999, "Should not scroll beyond content")
end
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end

View File

@@ -25,6 +25,9 @@ local testFiles = {
"testing/__tests__/theme_test.lua",
"testing/__tests__/layout_engine_test.lua",
"testing/__tests__/element_test.lua",
"testing/__tests__/overflow_test.lua",
"testing/__tests__/grid_test.lua",
"testing/__tests__/layout_edge_cases_test.lua",
}
local success = true