want things simpler

This commit is contained in:
Michael Freno
2025-12-12 19:15:27 -05:00
parent b714b6204c
commit 1d6ad6018f
10 changed files with 139 additions and 824 deletions

View File

@@ -16,7 +16,9 @@ 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
return function()
return require("modules." .. moduleName)
end
end
end)
@@ -46,7 +48,7 @@ function TestElementModeOverride:test_modeResolution_explicitImmediate()
mode = "immediate",
text = "Test",
})
luaunit.assertEquals(element._elementMode, "immediate")
end
@@ -56,7 +58,7 @@ function TestElementModeOverride:test_modeResolution_explicitRetained()
mode = "retained",
text = "Test",
})
luaunit.assertEquals(element._elementMode, "retained")
end
@@ -64,22 +66,22 @@ end
function TestElementModeOverride:test_modeResolution_nilUsesGlobalImmediate()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
local element = FlexLove.new({
text = "Test",
})
luaunit.assertEquals(element._elementMode, "immediate")
end
-- Test 04: Mode resolution - nil uses global (retained)
function TestElementModeOverride:test_modeResolution_nilUsesGlobalRetained()
FlexLove.setMode("retained")
local element = FlexLove.new({
text = "Test",
})
luaunit.assertEquals(element._elementMode, "retained")
end
@@ -92,7 +94,7 @@ function TestElementModeOverride:test_idGeneration_onlyForImmediate()
})
luaunit.assertNotNil(immediateEl.id)
luaunit.assertNotEquals(immediateEl.id, "")
-- Retained element without ID should have empty ID
local retainedEl = FlexLove.new({
mode = "retained",
@@ -104,13 +106,13 @@ end
-- Test 06: Immediate override in retained context
function TestElementModeOverride:test_immediateOverrideInRetainedContext()
FlexLove.setMode("retained")
local element = FlexLove.new({
mode = "immediate",
id = "test-immediate",
text = "Immediate in retained context",
})
luaunit.assertEquals(element._elementMode, "immediate")
luaunit.assertEquals(element.id, "test-immediate")
end
@@ -119,12 +121,12 @@ end
function TestElementModeOverride:test_retainedOverrideInImmediateContext()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
local element = FlexLove.new({
mode = "retained",
text = "Retained in immediate context",
})
luaunit.assertEquals(element._elementMode, "retained")
luaunit.assertEquals(element.id, "") -- Should not auto-generate ID
end
@@ -133,19 +135,19 @@ end
function TestElementModeOverride:test_mixedMode_immediateParent_retainedChild()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
local parent = FlexLove.new({
mode = "immediate",
id = "parent",
text = "Parent",
})
local child = FlexLove.new({
mode = "retained",
parent = parent,
text = "Child",
})
luaunit.assertEquals(parent._elementMode, "immediate")
luaunit.assertEquals(child._elementMode, "retained")
-- Child should not inherit parent mode
@@ -155,19 +157,19 @@ end
-- Test 09: Mixed-mode parent-child (retained parent, immediate child)
function TestElementModeOverride:test_mixedMode_retainedParent_immediateChild()
FlexLove.setMode("retained")
local parent = FlexLove.new({
mode = "retained",
text = "Parent",
})
local child = FlexLove.new({
mode = "immediate",
id = "child",
parent = parent,
text = "Child",
})
luaunit.assertEquals(parent._elementMode, "retained")
luaunit.assertEquals(child._elementMode, "immediate")
luaunit.assertEquals(child.id, "child")
@@ -177,24 +179,24 @@ end
function TestElementModeOverride:test_frameRegistration_onlyImmediate()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
local immediate1 = FlexLove.new({
mode = "immediate",
id = "imm1",
text = "Immediate 1",
})
local retained1 = FlexLove.new({
mode = "retained",
text = "Retained 1",
})
local immediate2 = FlexLove.new({
mode = "immediate",
id = "imm2",
text = "Immediate 2",
})
-- Count immediate elements in _currentFrameElements
local immediateCount = 0
for _, element in ipairs(FlexLove._currentFrameElements) do
@@ -202,14 +204,14 @@ function TestElementModeOverride:test_frameRegistration_onlyImmediate()
immediateCount = immediateCount + 1
end
end
luaunit.assertEquals(immediateCount, 2)
end
-- Test 11: Layout calculation for retained parent with immediate children
function TestElementModeOverride:test_layoutRetainedParentWithImmediateChildren()
FlexLove.setMode("retained")
-- Create retained parent with flex layout
local parent = FlexLove.new({
mode = "retained",
@@ -219,11 +221,11 @@ function TestElementModeOverride:test_layoutRetainedParentWithImmediateChildren(
flexDirection = "horizontal",
gap = 10,
})
-- Switch to immediate mode and add children
FlexLove.setMode("immediate")
FlexLove.beginFrame()
local child1 = FlexLove.new({
mode = "immediate",
id = "child1",
@@ -231,7 +233,7 @@ function TestElementModeOverride:test_layoutRetainedParentWithImmediateChildren(
width = 100,
height = 50,
})
local child2 = FlexLove.new({
mode = "immediate",
id = "child2",
@@ -239,9 +241,9 @@ function TestElementModeOverride:test_layoutRetainedParentWithImmediateChildren(
width = 100,
height = 50,
})
FlexLove.endFrame()
-- Verify children are positioned correctly by flex layout
luaunit.assertEquals(child1.x, 0)
luaunit.assertEquals(child1.y, 0)
@@ -253,7 +255,7 @@ end
function TestElementModeOverride:test_deeplyNestedMixedModes()
FlexLove.setMode("immediate")
FlexLove.beginFrame()
-- Level 1: Retained root
local root = FlexLove.new({
mode = "retained",
@@ -263,7 +265,7 @@ function TestElementModeOverride:test_deeplyNestedMixedModes()
flexDirection = "vertical",
gap = 5,
})
-- Level 2: Immediate child of retained parent
local middle = FlexLove.new({
mode = "immediate",
@@ -275,7 +277,7 @@ function TestElementModeOverride:test_deeplyNestedMixedModes()
flexDirection = "horizontal",
gap = 10,
})
-- Level 3: Retained grandchildren
local leaf1 = FlexLove.new({
mode = "retained",
@@ -283,16 +285,16 @@ function TestElementModeOverride:test_deeplyNestedMixedModes()
width = 100,
height = 50,
})
local leaf2 = FlexLove.new({
mode = "retained",
parent = middle,
width = 100,
height = 50,
})
FlexLove.endFrame()
-- Verify all levels are positioned correctly
luaunit.assertEquals(root.x, 0)
luaunit.assertEquals(root.y, 0)
@@ -307,20 +309,20 @@ end
-- Test 13: Immediate children of retained parents receive updates
function TestElementModeOverride:test_immediateChildrenOfRetainedParentsGetUpdated()
FlexLove.setMode("retained")
local updateCount = 0
-- Create retained parent
local parent = FlexLove.new({
mode = "retained",
width = 800,
height = 600,
})
-- Switch to immediate mode for child
FlexLove.setMode("immediate")
FlexLove.beginFrame()
-- Create immediate child that tracks updates
local child = FlexLove.new({
mode = "immediate",
@@ -329,15 +331,17 @@ function TestElementModeOverride:test_immediateChildrenOfRetainedParentsGetUpdat
width = 100,
height = 50,
})
-- Manually call update on the child to simulate what endFrame should do
-- In the real implementation, endFrame calls update on retained parents,
-- which cascades to immediate children
FlexLove.endFrame()
-- The child should be in the state manager
local state = StateManager.getState("updateTest")
luaunit.assertNotNil(state)
end
os.exit(luaunit.LuaUnit.run())
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end

View File

@@ -54,12 +54,9 @@ end
function TestModuleLoader:test_safeRequire_throws_error_for_missing_required_module()
-- Test loading a non-existent required module should throw error
lu.assertErrorMsgContains(
"Required module",
function()
ModuleLoader.safeRequire(modulePath .. "modules.NonExistentModule", false)
end
)
lu.assertErrorMsgContains("Required module", function()
ModuleLoader.safeRequire(modulePath .. "modules.NonExistentModule", false)
end)
end
function TestModuleLoader:test_stub_has_safe_init_method()
@@ -116,7 +113,7 @@ function TestModuleLoader:test_stub_returns_function_for_unknown_properties()
-- Unknown properties should return no-op functions for safe method calls
lu.assertIsFunction(stub.unknownProperty)
lu.assertIsFunction(stub.anotherUnknownProperty)
-- Calling unknown methods should not error
stub:unknownMethod()
stub:anotherUnknownMethod("arg1", "arg2")
@@ -197,5 +194,3 @@ end
if not _G.RUNNING_ALL_TESTS then
os.exit(lu.LuaUnit.run())
end
return TestModuleLoader

View File

@@ -1,6 +1,6 @@
--[[
Test: Retained Elements in Immediate Mode (No Duplication)
This test verifies that retained-mode elements don't get recreated
when the overall application is in immediate mode.
]]
@@ -39,34 +39,34 @@ function TestRetainedInImmediateMode:test_topLevelRetainedElementPersists()
})
return backdrop
end
FlexLove.beginFrame()
-- Frame 1: Create a retained element (no explicit ID)
local backdrop = createUI()
local backdropId = backdrop.id
luaunit.assertNotNil(backdropId, "Backdrop should have auto-generated ID")
luaunit.assertEquals(backdrop._elementMode, "retained")
FlexLove.endFrame()
-- Frame 2: Call createUI() again (same function, same line numbers)
FlexLove.beginFrame()
local backdrop2 = createUI()
-- Should return the SAME element, not create a new one
luaunit.assertEquals(backdrop2.id, backdropId, "Should return existing element with same ID")
luaunit.assertEquals(backdrop2, backdrop, "Should return exact same element instance")
FlexLove.endFrame()
end
-- Test that retained elements with explicit IDs can be recreated
function TestRetainedInImmediateMode:test_explicitIdAllowsNewElements()
FlexLove.beginFrame()
-- Create element with explicit ID
local element1 = FlexLove.new({
id = "my_custom_id",
@@ -75,26 +75,26 @@ function TestRetainedInImmediateMode:test_explicitIdAllowsNewElements()
height = 100,
backgroundColor = Color.new(1, 0, 0, 1),
})
FlexLove.endFrame()
FlexLove.beginFrame()
-- Create another element with SAME explicit ID but different properties
-- This should create a NEW element (user controls uniqueness)
local element2 = FlexLove.new({
id = "my_custom_id",
mode = "retained",
width = 200, -- Different properties
width = 200, -- Different properties
height = 200,
backgroundColor = Color.new(0, 1, 0, 1),
})
-- With explicit IDs, we allow duplicates (user responsibility)
luaunit.assertEquals(element2.id, "my_custom_id")
-- Properties should match NEW element, not old
luaunit.assertEquals(element2.width, 200)
FlexLove.endFrame()
end
@@ -106,38 +106,38 @@ function TestRetainedInImmediateMode:test_multipleRetainedElementsPersist()
width = "100%",
height = "100%",
})
local window = FlexLove.new({
mode = "retained",
width = "90%",
height = "90%",
})
return backdrop, window
end
FlexLove.beginFrame()
local backdrop, window = createUI()
local backdropId = backdrop.id
local windowId = window.id
luaunit.assertNotEquals(backdropId, windowId, "Different elements should have different IDs")
FlexLove.endFrame()
-- Frame 2
FlexLove.beginFrame()
local backdrop2, window2 = createUI()
-- Both should return existing elements
luaunit.assertEquals(backdrop2.id, backdropId)
luaunit.assertEquals(window2.id, windowId)
luaunit.assertEquals(backdrop2, backdrop)
luaunit.assertEquals(window2, window)
FlexLove.endFrame()
end
@@ -149,45 +149,46 @@ function TestRetainedInImmediateMode:test_retainedChildOfRetainedParentPersists(
width = 400,
height = 400,
})
local child = FlexLove.new({
mode = "retained",
parent = parent,
width = 100,
height = 100,
})
return parent, child
end
FlexLove.beginFrame()
local parent, child = createUI()
local parentId = parent.id
local childId = child.id
FlexLove.endFrame()
-- Frame 2
FlexLove.beginFrame()
local parent2, child2 = createUI()
-- Parent should be the same
luaunit.assertEquals(parent2.id, parentId)
luaunit.assertEquals(parent2, parent)
-- Child should also be the same instance
luaunit.assertEquals(child2.id, childId, "Child ID should match")
luaunit.assertEquals(child2, child, "Child should be same instance")
-- Child should still exist in parent's children
luaunit.assertEquals(#parent2.children, 1, "Parent should have exactly 1 child")
luaunit.assertEquals(parent2.children[1].id, childId)
FlexLove.endFrame()
end
-- Run tests
os.exit(luaunit.LuaUnit.run())
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end

View File

@@ -1,6 +1,6 @@
--[[
Test: Retained Elements with Varying Props (ID Stability)
This test verifies that retained-mode elements return the same instance
across frames even when props vary slightly (e.g., different Color instances).
]]
@@ -30,33 +30,33 @@ end
-- Test that retained elements persist despite creating new Color instances
function TestRetainedPropStability:test_retainedElementIgnoresColorInstanceChanges()
FlexLove.beginFrame()
-- Frame 1: Create retained element with Color instance
local backdrop1 = FlexLove.new({
mode = "retained",
width = "100%",
height = "100%",
backgroundColor = Color.new(1, 1, 1, 0.1), -- NEW Color instance
backgroundColor = Color.new(1, 1, 1, 0.1), -- NEW Color instance
})
local id1 = backdrop1.id
FlexLove.endFrame()
-- Frame 2: Same props but NEW Color instance (common pattern in user code)
FlexLove.beginFrame()
local backdrop2 = FlexLove.new({
mode = "retained",
width = "100%",
height = "100%",
backgroundColor = Color.new(1, 1, 1, 0.1), -- NEW Color instance (different table)
backgroundColor = Color.new(1, 1, 1, 0.1), -- NEW Color instance (different table)
})
-- Should return SAME element despite different Color instance
luaunit.assertEquals(backdrop2.id, id1, "ID should be stable across frames")
luaunit.assertEquals(backdrop2, backdrop1, "Should return same element instance")
FlexLove.endFrame()
end
@@ -81,23 +81,23 @@ function TestRetainedPropStability:test_retainedElementWithComplexProps()
gap = 10,
})
end
FlexLove.beginFrame()
local window1 = createWindow()
local id1 = window1.id
FlexLove.endFrame()
-- Frame 2: Same function, same props
FlexLove.beginFrame()
local window2 = createWindow()
-- Should return same element
luaunit.assertEquals(window2.id, id1)
luaunit.assertEquals(window2, window1)
FlexLove.endFrame()
end
@@ -108,27 +108,27 @@ function TestRetainedPropStability:test_retainedElementWithBackdropBlur()
mode = "retained",
width = "100%",
height = "100%",
backdropBlur = { radius = 10 }, -- Table prop
backdropBlur = { radius = 10 }, -- Table prop
backgroundColor = Color.new(1, 1, 1, 0.1),
})
end
FlexLove.beginFrame()
local backdrop1 = createBackdrop()
local id1 = backdrop1.id
FlexLove.endFrame()
-- Frame 2
FlexLove.beginFrame()
local backdrop2 = createBackdrop()
-- Should return same element
luaunit.assertEquals(backdrop2.id, id1)
luaunit.assertEquals(backdrop2, backdrop1)
FlexLove.endFrame()
end
@@ -143,7 +143,7 @@ function TestRetainedPropStability:test_multipleRetainedElementsWithVaryingProps
backdropBlur = { radius = 10 },
backgroundColor = Color.new(1, 1, 1, 0.1),
})
local window = FlexLove.new({
mode = "retained",
z = 100,
@@ -154,31 +154,32 @@ function TestRetainedPropStability:test_multipleRetainedElementsWithVaryingProps
themeComponent = "framev3",
padding = { horizontal = "5%", vertical = "3%" },
})
return backdrop, window
end
FlexLove.beginFrame()
local backdrop1, window1 = createUI()
local backdropId = backdrop1.id
local windowId = window1.id
FlexLove.endFrame()
-- Frame 2: New Color instances, new table instances for props
FlexLove.beginFrame()
local backdrop2, window2 = createUI()
-- Both should return existing elements
luaunit.assertEquals(backdrop2.id, backdropId)
luaunit.assertEquals(window2.id, windowId)
luaunit.assertEquals(backdrop2, backdrop1)
luaunit.assertEquals(window2, window1)
FlexLove.endFrame()
end
-- Run tests
os.exit(luaunit.LuaUnit.run())
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())
end

View File

@@ -1059,7 +1059,7 @@ function TestScrollManagerEdgeCases:testScrollbarKnobOffsetDefault()
-- When not provided, scrollbarKnobOffset should be nil (use theme default)
local sm = createScrollManager({})
luaunit.assertNil(sm.scrollbarKnobOffset)
-- When explicitly set to 0, it should be normalized
local sm2 = createScrollManager({ scrollbarKnobOffset = 0 })
luaunit.assertNotNil(sm2.scrollbarKnobOffset)
@@ -1073,7 +1073,7 @@ function TestScrollManagerEdgeCases:testScrollbarKnobOffsetStatePersistence()
local sm = createScrollManager({ scrollbarKnobOffset = { x = 5, y = 10 } })
local state = sm:getState()
luaunit.assertNotNil(state.scrollbarKnobOffset)
local sm2 = createScrollManager({})
sm2:setState(state)
luaunit.assertEquals(sm2.scrollbarKnobOffset.x, 5)

View File

@@ -373,9 +373,6 @@ function TestThemeValidation:test_validate_valid_colors()
luaunit.assertEquals(#errors, 0)
end
function TestThemeValidation:test_validate_colors_non_table()
local theme = {
name = "Test Theme",
@@ -726,7 +723,6 @@ function TestThemeValidation:test_sanitize_nil_theme()
luaunit.assertEquals(sanitized.name, "Invalid Theme")
end
function TestThemeValidation:test_sanitize_theme_with_non_string_name()
local theme = {
name = 123,
@@ -735,7 +731,6 @@ function TestThemeValidation:test_sanitize_theme_with_non_string_name()
luaunit.assertEquals(type(sanitized.name), "string")
end
function TestThemeValidation:test_sanitize_removes_non_string_color_names()
local theme = {
name = "Test",
@@ -774,8 +769,6 @@ end
-- === Complex Theme Validation ===
-- Run tests if this file is executed directly
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run())

View File

@@ -38,32 +38,33 @@ local luaunit = require("testing.luaunit")
local testFiles = {
"testing/__tests__/animation_test.lua",
"testing/__tests__/blur_test.lua",
"testing/__tests__/calc_test.lua",
"testing/__tests__/critical_failures_test.lua",
"testing/__tests__/element_test.lua",
"testing/__tests__/element_mode_override_test.lua",
"testing/__tests__/event_handler_test.lua",
"testing/__tests__/flexlove_test.lua",
"testing/__tests__/grid_test.lua",
"testing/__tests__/image_cache_test.lua",
"testing/__tests__/image_renderer_test.lua",
"testing/__tests__/image_scaler_test.lua",
"testing/__tests__/input_event_test.lua",
"testing/__tests__/layout_engine_test.lua",
"testing/__tests__/mixed_mode_events_test.lua",
"testing/__tests__/mixed_mode_children_test.lua",
"testing/__tests__/retained_in_immediate_test.lua",
"testing/__tests__/mixed_mode_events_test.lua",
"testing/__tests__/module_loader_test.lua",
"testing/__tests__/ninepatch_test.lua",
"testing/__tests__/performance_test.lua",
"testing/__tests__/renderer_test.lua",
"testing/__tests__/retained_in_immediate_test.lua",
"testing/__tests__/retained_prop_stability_test.lua",
"testing/__tests__/roundedrect_test.lua",
"testing/__tests__/scroll_manager_test.lua",
"testing/__tests__/text_editor_test.lua",
"testing/__tests__/theme_test.lua",
"testing/__tests__/touch_events_test.lua",
"testing/__tests__/units_test.lua",
"testing/__tests__/utils_test.lua",
"testing/__tests__/calc_test.lua",
-- Feature/Integration tests
"testing/__tests__/critical_failures_test.lua",
"testing/__tests__/flexlove_test.lua",
"testing/__tests__/touch_events_test.lua",
}
local success = true