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

@@ -1,186 +0,0 @@
-- Example demonstrating hover and unhover events in FlexLöve
-- This shows how to use the new hover/unhover events for interactive UI elements
local FlexLove = require("FlexLove")
function love.load()
FlexLove.init({
baseScale = { width = 1920, height = 1080 },
immediateMode = true,
autoFrameManagement = false,
})
end
-- State to track hover status
local hoverStatus = "Not hovering"
local hoverCount = 0
local unhoverCount = 0
local lastEventTime = 0
function love.update(dt)
FlexLove.beginFrame()
-- Create a container
FlexLove.new({
width = "100vw",
height = "100vh",
backgroundColor = FlexLove.Color.fromHex("#1a1a2e"),
positioning = "flex",
flexDirection = "vertical",
justifyContent = "center",
alignItems = "center",
gap = 30,
})
-- Title
FlexLove.new({
text = "Hover Event Demo",
textSize = "4xl",
textColor = FlexLove.Color.fromHex("#ffffff"),
})
-- Instructions
FlexLove.new({
text = "Move your mouse over the boxes below to see hover events",
textSize = "lg",
textColor = FlexLove.Color.fromHex("#a0a0a0"),
})
-- Status display
FlexLove.new({
text = hoverStatus,
textSize = "xl",
textColor = FlexLove.Color.fromHex("#4ecca3"),
padding = 20,
})
-- Event counters
FlexLove.new({
text = string.format("Hover events: %d | Unhover events: %d", hoverCount, unhoverCount),
textSize = "md",
textColor = FlexLove.Color.fromHex("#ffffff"),
})
-- Container for hover boxes
local boxContainer = FlexLove.new({
positioning = "flex",
flexDirection = "horizontal",
gap = 30,
})
-- Hover Box 1
FlexLove.new({
parent = boxContainer,
width = 200,
height = 200,
backgroundColor = FlexLove.Color.fromHex("#e94560"),
cornerRadius = 15,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
text = "Hover Me!",
textSize = "xl",
textColor = FlexLove.Color.fromHex("#ffffff"),
onEvent = function(element, event)
if event.type == "hover" then
hoverStatus = "Hovering over RED box!"
hoverCount = hoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "unhover" then
hoverStatus = "Left RED box"
unhoverCount = unhoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "click" then
print("Clicked RED box!")
end
end,
})
-- Hover Box 2
FlexLove.new({
parent = boxContainer,
width = 200,
height = 200,
backgroundColor = FlexLove.Color.fromHex("#4ecca3"),
cornerRadius = 15,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
text = "Hover Me!",
textSize = "xl",
textColor = FlexLove.Color.fromHex("#1a1a2e"),
onEvent = function(element, event)
if event.type == "hover" then
hoverStatus = "Hovering over GREEN box!"
hoverCount = hoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "unhover" then
hoverStatus = "Left GREEN box"
unhoverCount = unhoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "click" then
print("Clicked GREEN box!")
end
end,
})
-- Hover Box 3
FlexLove.new({
parent = boxContainer,
width = 200,
height = 200,
backgroundColor = FlexLove.Color.fromHex("#0f3460"),
cornerRadius = 15,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
text = "Hover Me!",
textSize = "xl",
textColor = FlexLove.Color.fromHex("#ffffff"),
onEvent = function(element, event)
if event.type == "hover" then
hoverStatus = "Hovering over BLUE box!"
hoverCount = hoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "unhover" then
hoverStatus = "Left BLUE box"
unhoverCount = unhoverCount + 1
lastEventTime = love.timer.getTime()
elseif event.type == "click" then
print("Clicked BLUE box!")
end
end,
})
-- Reset button
FlexLove.new({
width = 200,
height = 50,
backgroundColor = FlexLove.Color.fromHex("#e94560"),
cornerRadius = 25,
positioning = "flex",
justifyContent = "center",
alignItems = "center",
text = "Reset Counters",
textSize = "md",
textColor = FlexLove.Color.fromHex("#ffffff"),
margin = { top = 30 },
onEvent = function(element, event)
if event.type == "click" then
hoverCount = 0
unhoverCount = 0
hoverStatus = "Counters reset!"
end
end,
})
FlexLove.endFrame()
end
function love.draw()
FlexLove.draw()
end
function love.resize(w, h)
FlexLove.resize(w, h)
end

View File

@@ -1,219 +0,0 @@
-- Demo: Retained children with immediate parents
-- Shows how retained-mode children persist when immediate-mode parents recreate each frame
local FlexLove = require("FlexLove")
-- Track frame count for demo
local frameCount = 0
-- Retained button state (will persist across frames)
local buttonClicks = 0
local topLevelButtonClicks = 0
function love.load()
love.window.setTitle("Mixed-Mode Demo: Retained Children + Immediate Parents")
love.window.setMode(800, 600)
FlexLove.init({
immediateMode = true,
performanceMonitoring = true,
})
end
function love.update(dt)
FlexLove.update(dt)
end
function love.draw()
FlexLove.beginFrame()
-- Frame counter (immediate mode - recreates each frame)
local header = FlexLove.new({
width = 800,
height = 60,
backgroundColor = { 0.1, 0.1, 0.15, 1 },
padding = 20,
flexDirection = "horizontal",
justifyContent = "space-between",
alignItems = "center",
})
FlexLove.new({
parent = header,
text = "Frame: " .. frameCount,
textColor = { 1, 1, 1, 1 },
textSize = 20,
})
FlexLove.new({
parent = header,
text = "Mixed-Mode Element Tree Demo",
textColor = { 0.8, 0.9, 1, 1 },
textSize = 24,
})
-- Main content area (immediate parent)
local container = FlexLove.new({
id = "main_container",
y = 60,
width = 800,
height = 540,
padding = 30,
gap = 20,
backgroundColor = { 0.05, 0.05, 0.08, 1 },
flexDirection = "vertical",
})
-- Section 1: Retained button in immediate parent
FlexLove.new({
parent = container,
text = "1. Retained Button (persists across frames)",
textColor = { 0.9, 0.9, 0.9, 1 },
textSize = 18,
})
local retainedButton = FlexLove.new({
id = "retained_button",
mode = "retained", -- This button will persist!
parent = container,
width = 300,
height = 50,
backgroundColor = { 0.2, 0.6, 0.9, 1 },
cornerRadius = 8,
text = "Clicks: " .. buttonClicks,
textColor = { 1, 1, 1, 1 },
textSize = 16,
textAlign = "center",
onEvent = function(element, event)
if event.type == "click" then
buttonClicks = buttonClicks + 1
-- Update button text
element.text = "Clicks: " .. buttonClicks
end
end,
})
FlexLove.new({
parent = container,
text = "Note: Button state persists even though parent recreates every frame",
textColor = { 0.6, 0.6, 0.6, 1 },
textSize = 12,
})
-- Section 2: Top-level retained element
FlexLove.new({
parent = container,
text = "2. Top-Level Retained Element (also persists)",
textColor = { 0.9, 0.9, 0.9, 1 },
textSize = 18,
margin = { top = 20 },
})
FlexLove.new({
parent = container,
text = "Look at the bottom-left corner for a persistent panel",
textColor = { 0.6, 0.6, 0.6, 1 },
textSize = 12,
})
-- Section 3: Comparison with immediate button
FlexLove.new({
parent = container,
text = "3. Immediate Button (recreates every frame)",
textColor = { 0.9, 0.9, 0.9, 1 },
textSize = 18,
margin = { top = 20 },
})
FlexLove.new({
parent = container,
width = 300,
height = 50,
backgroundColor = { 0.9, 0.3, 0.3, 1 },
cornerRadius = 8,
text = "Can't track clicks (recreated)",
textColor = { 1, 1, 1, 1 },
textSize = 16,
textAlign = "center",
onEvent = function(element, event)
if event.type == "click" then
print("Immediate button clicked (but counter can't persist)")
end
end,
})
FlexLove.new({
parent = container,
text = "Note: This button is recreated every frame, so it can't maintain state",
textColor = { 0.6, 0.6, 0.6, 1 },
textSize = 12,
})
-- Top-level retained element (persists in immediate mode!)
local topLevelPanel = FlexLove.new({
id = "top_level_panel",
mode = "retained",
x = 10,
y = 500,
width = 250,
height = 90,
backgroundColor = { 0.15, 0.5, 0.3, 1 },
cornerRadius = 10,
padding = 15,
gap = 10,
flexDirection = "vertical",
})
FlexLove.new({
id = "panel_title",
mode = "retained",
parent = topLevelPanel,
text = "Persistent Panel",
textColor = { 1, 1, 1, 1 },
textSize = 16,
})
FlexLove.new({
id = "panel_button",
mode = "retained",
parent = topLevelPanel,
width = 220,
height = 35,
backgroundColor = { 1, 1, 1, 0.9 },
cornerRadius = 5,
text = "Panel Clicks: " .. topLevelButtonClicks,
textColor = { 0.15, 0.5, 0.3, 1 },
textSize = 14,
textAlign = "center",
onEvent = function(element, event)
if event.type == "click" then
topLevelButtonClicks = topLevelButtonClicks + 1
element.text = "Panel Clicks: " .. topLevelButtonClicks
end
end,
})
FlexLove.endFrame()
-- Increment frame counter AFTER drawing
frameCount = frameCount + 1
-- Draw all UI elements
FlexLove.draw()
end
function love.mousepressed(x, y, button)
FlexLove.mousepressed(x, y, button)
end
function love.mousereleased(x, y, button)
FlexLove.mousereleased(x, y, button)
end
function love.mousemoved(x, y, dx, dy)
FlexLove.mousemoved(x, y, dx, dy)
end
function love.wheelmoved(x, y)
FlexLove.wheelmoved(x, y)
end

View File

@@ -1,275 +0,0 @@
-- Mode Override Demo
-- Demonstrates per-element mode override in FlexLöve
-- Shows how to mix immediate and retained mode elements in the same application
package.path = package.path .. ";../?.lua;../modules/?.lua"
local FlexLove = require("FlexLove")
local Color = require("modules.Color")
-- Global state
local frameCount = 0
local clickCount = 0
local retainedPanelCreated = false
local retainedPanel = nil
function love.load()
-- Initialize FlexLove in immediate mode globally
FlexLove.init({
immediateMode = true,
theme = "space",
})
love.window.setTitle("Mode Override Demo - FlexLöve")
love.window.setMode(1200, 800)
end
function love.update(dt)
FlexLove.update(dt)
frameCount = frameCount + 1
end
function love.draw()
love.graphics.clear(0.1, 0.1, 0.15, 1)
FlexLove.beginFrame()
-- Title - Immediate mode (default, recreated every frame)
FlexLove.new({
text = "Mode Override Demo",
textSize = 32,
textColor = Color.new(1, 1, 1, 1),
width = "100vw",
height = 60,
textAlign = "center",
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
padding = { top = 15, bottom = 15 },
})
-- Container for demo panels
local container = FlexLove.new({
positioning = "flex",
flexDirection = "horizontal",
justifyContent = "center",
alignItems = "flex-start",
gap = 20,
width = "100vw",
height = "calc(100vh - 60px)",
padding = { top = 20, left = 20, right = 20, bottom = 20 },
})
-- LEFT PANEL: Immediate Mode (Dynamic, recreated every frame)
local leftPanel = FlexLove.new({
mode = "immediate", -- Explicit immediate mode (would be default anyway)
parent = container,
width = "45vw",
height = "calc(100vh - 100px)",
backgroundColor = Color.new(0.15, 0.15, 0.2, 0.95),
cornerRadius = 8,
padding = { top = 20, left = 20, right = 20, bottom = 20 },
positioning = "flex",
flexDirection = "vertical",
gap = 15,
})
-- Panel title
FlexLove.new({
parent = leftPanel,
text = "Immediate Mode Panel",
textSize = 24,
textColor = Color.new(0.4, 0.8, 1, 1),
width = "100%",
height = 40,
})
-- Description
FlexLove.new({
parent = leftPanel,
text = "Elements in this panel are recreated every frame.\nState is preserved by StateManager.",
textSize = 14,
textColor = Color.new(0.8, 0.8, 0.8, 1),
width = "100%",
height = 60,
})
-- Live frame counter (updates automatically)
FlexLove.new({
parent = leftPanel,
text = string.format("Frame: %d", frameCount),
textSize = 18,
textColor = Color.new(1, 1, 0.5, 1),
width = "100%",
height = 30,
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
padding = { top = 5, left = 10, right = 10, bottom = 5 },
cornerRadius = 4,
})
-- Click counter (updates automatically)
FlexLove.new({
parent = leftPanel,
text = string.format("Clicks: %d", clickCount),
textSize = 18,
textColor = Color.new(0.5, 1, 0.5, 1),
width = "100%",
height = 30,
backgroundColor = Color.new(0.2, 0.2, 0.3, 1),
padding = { top = 5, left = 10, right = 10, bottom = 5 },
cornerRadius = 4,
})
-- Interactive button (state preserved across frames)
FlexLove.new({
parent = leftPanel,
text = "Click Me! (Immediate Mode)",
textSize = 16,
textColor = Color.new(1, 1, 1, 1),
width = "100%",
height = 50,
themeComponent = "button",
onEvent = function(element, event)
if event.type == "release" then
clickCount = clickCount + 1
end
end,
})
-- Info box
FlexLove.new({
parent = leftPanel,
text = "Notice how the frame counter updates\nautomatically without any manual updates.\n\nThis is the power of immediate mode:\nUI reflects application state automatically.",
textSize = 13,
textColor = Color.new(0.7, 0.7, 0.7, 1),
width = "100%",
height = "auto",
backgroundColor = Color.new(0.1, 0.1, 0.15, 1),
padding = { top = 10, left = 10, right = 10, bottom = 10 },
cornerRadius = 4,
})
-- RIGHT PANEL: Retained Mode (Static, created once)
-- Only create on first frame
if not retainedPanelCreated then
retainedPanel = FlexLove.new({
mode = "retained", -- Explicit retained mode override
parent = container,
width = "45vw",
height = "calc(100vh - 100px)",
backgroundColor = Color.new(0.2, 0.15, 0.15, 0.95),
cornerRadius = 8,
padding = { top = 20, left = 20, right = 20, bottom = 20 },
positioning = "flex",
flexDirection = "vertical",
gap = 15,
})
-- Panel title (retained)
FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = "Retained Mode Panel",
textSize = 24,
textColor = Color.new(1, 0.6, 0.4, 1),
width = "100%",
height = 40,
})
-- Description (retained)
FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = "Elements in this panel are created once\nand persist across frames.",
textSize = 14,
textColor = Color.new(0.8, 0.8, 0.8, 1),
width = "100%",
height = 60,
})
-- Static frame counter (won't update)
local staticCounter = FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = string.format("Created at frame: %d", frameCount),
textSize = 18,
textColor = Color.new(1, 1, 0.5, 1),
width = "100%",
height = 30,
backgroundColor = Color.new(0.3, 0.2, 0.2, 1),
padding = { top = 5, left = 10, right = 10, bottom = 5 },
cornerRadius = 4,
})
-- Click counter placeholder (must be manually updated)
local retainedClickCounter = FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = string.format("Clicks: %d (manual update needed)", clickCount),
textSize = 18,
textColor = Color.new(0.5, 1, 0.5, 1),
width = "100%",
height = 30,
backgroundColor = Color.new(0.3, 0.2, 0.2, 1),
padding = { top = 5, left = 10, right = 10, bottom = 5 },
cornerRadius = 4,
})
-- Interactive button with manual update
FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = "Click Me! (Retained Mode)",
textSize = 16,
textColor = Color.new(1, 1, 1, 1),
width = "100%",
height = 50,
themeComponent = "button",
onEvent = function(element, event)
if event.type == "release" then
clickCount = clickCount + 1
-- In retained mode, we must manually update the UI
retainedClickCounter.text = string.format("Clicks: %d (manual update needed)", clickCount)
end
end,
})
-- Info box (retained)
FlexLove.new({
mode = "retained",
parent = retainedPanel,
text = "Notice how this panel's elements\ndon't update automatically.\n\nIn retained mode, you must manually\nupdate element properties when state changes.\n\nThis gives better performance for\nstatic UI elements.",
textSize = 13,
textColor = Color.new(0.7, 0.7, 0.7, 1),
width = "100%",
height = "auto",
backgroundColor = Color.new(0.15, 0.1, 0.1, 1),
padding = { top = 10, left = 10, right = 10, bottom = 10 },
cornerRadius = 4,
})
retainedPanelCreated = true
end
FlexLove.endFrame()
-- Bottom instructions
love.graphics.setColor(0.5, 0.5, 0.5, 1)
love.graphics.print("Global mode: Immediate | Left panel: Immediate (explicit) | Right panel: Retained (override)", 10, love.graphics.getHeight() - 30)
love.graphics.print("Press ESC to quit", 10, love.graphics.getHeight() - 15)
end
function love.keypressed(key)
if key == "escape" then
love.event.quit()
end
end
function love.mousepressed(x, y, button)
FlexLove.mousepressed(x, y, button)
end
function love.mousereleased(x, y, button)
FlexLove.mousereleased(x, y, button)
end
function love.mousemoved(x, y, dx, dy)
FlexLove.mousemoved(x, y, dx, dy)
end

View File

@@ -16,7 +16,9 @@ local originalSearchers = package.searchers or package.loaders
table.insert(originalSearchers, 2, function(modname) table.insert(originalSearchers, 2, function(modname)
if modname:match("^FlexLove%.modules%.") then if modname:match("^FlexLove%.modules%.") then
local moduleName = modname:gsub("^FlexLove%.modules%.", "") local moduleName = modname:gsub("^FlexLove%.modules%.", "")
return function() return require("modules." .. moduleName) end return function()
return require("modules." .. moduleName)
end
end end
end) end)
@@ -340,4 +342,6 @@ function TestElementModeOverride:test_immediateChildrenOfRetainedParentsGetUpdat
luaunit.assertNotNil(state) luaunit.assertNotNil(state)
end end
if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run()) os.exit(luaunit.LuaUnit.run())
end

View File

@@ -54,12 +54,9 @@ end
function TestModuleLoader:test_safeRequire_throws_error_for_missing_required_module() function TestModuleLoader:test_safeRequire_throws_error_for_missing_required_module()
-- Test loading a non-existent required module should throw error -- Test loading a non-existent required module should throw error
lu.assertErrorMsgContains( lu.assertErrorMsgContains("Required module", function()
"Required module",
function()
ModuleLoader.safeRequire(modulePath .. "modules.NonExistentModule", false) ModuleLoader.safeRequire(modulePath .. "modules.NonExistentModule", false)
end end)
)
end end
function TestModuleLoader:test_stub_has_safe_init_method() function TestModuleLoader:test_stub_has_safe_init_method()
@@ -197,5 +194,3 @@ end
if not _G.RUNNING_ALL_TESTS then if not _G.RUNNING_ALL_TESTS then
os.exit(lu.LuaUnit.run()) os.exit(lu.LuaUnit.run())
end end
return TestModuleLoader

View File

@@ -189,5 +189,6 @@ function TestRetainedInImmediateMode:test_retainedChildOfRetainedParentPersists(
FlexLove.endFrame() FlexLove.endFrame()
end end
-- Run tests if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run()) os.exit(luaunit.LuaUnit.run())
end

View File

@@ -180,5 +180,6 @@ function TestRetainedPropStability:test_multipleRetainedElementsWithVaryingProps
FlexLove.endFrame() FlexLove.endFrame()
end end
-- Run tests if not _G.RUNNING_ALL_TESTS then
os.exit(luaunit.LuaUnit.run()) os.exit(luaunit.LuaUnit.run())
end

View File

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

View File

@@ -38,32 +38,33 @@ local luaunit = require("testing.luaunit")
local testFiles = { local testFiles = {
"testing/__tests__/animation_test.lua", "testing/__tests__/animation_test.lua",
"testing/__tests__/blur_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_test.lua",
"testing/__tests__/element_mode_override_test.lua",
"testing/__tests__/event_handler_test.lua", "testing/__tests__/event_handler_test.lua",
"testing/__tests__/flexlove_test.lua",
"testing/__tests__/grid_test.lua", "testing/__tests__/grid_test.lua",
"testing/__tests__/image_cache_test.lua", "testing/__tests__/image_cache_test.lua",
"testing/__tests__/image_renderer_test.lua", "testing/__tests__/image_renderer_test.lua",
"testing/__tests__/image_scaler_test.lua", "testing/__tests__/image_scaler_test.lua",
"testing/__tests__/input_event_test.lua", "testing/__tests__/input_event_test.lua",
"testing/__tests__/layout_engine_test.lua", "testing/__tests__/layout_engine_test.lua",
"testing/__tests__/mixed_mode_events_test.lua",
"testing/__tests__/mixed_mode_children_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__/module_loader_test.lua",
"testing/__tests__/ninepatch_test.lua", "testing/__tests__/ninepatch_test.lua",
"testing/__tests__/performance_test.lua", "testing/__tests__/performance_test.lua",
"testing/__tests__/renderer_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__/roundedrect_test.lua",
"testing/__tests__/scroll_manager_test.lua", "testing/__tests__/scroll_manager_test.lua",
"testing/__tests__/text_editor_test.lua", "testing/__tests__/text_editor_test.lua",
"testing/__tests__/theme_test.lua", "testing/__tests__/theme_test.lua",
"testing/__tests__/touch_events_test.lua",
"testing/__tests__/units_test.lua", "testing/__tests__/units_test.lua",
"testing/__tests__/utils_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 local success = true