merging tests
This commit is contained in:
@@ -376,6 +376,9 @@ function Element.new(props, deps)
|
|||||||
end
|
end
|
||||||
self.opacity = props.opacity or 1
|
self.opacity = props.opacity or 1
|
||||||
|
|
||||||
|
-- Set visibility property (default: "visible")
|
||||||
|
self.visibility = props.visibility or "visible"
|
||||||
|
|
||||||
-- Handle cornerRadius (can be number or table)
|
-- Handle cornerRadius (can be number or table)
|
||||||
if props.cornerRadius then
|
if props.cornerRadius then
|
||||||
if type(props.cornerRadius) == "number" then
|
if type(props.cornerRadius) == "number" then
|
||||||
@@ -1689,6 +1692,74 @@ function Element:addChild(child)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove a specific child from this element
|
||||||
|
---@param child Element
|
||||||
|
function Element:removeChild(child)
|
||||||
|
for i, c in ipairs(self.children) do
|
||||||
|
if c == child then
|
||||||
|
table.remove(self.children, i)
|
||||||
|
child.parent = nil
|
||||||
|
|
||||||
|
-- Recalculate auto-sizing if needed
|
||||||
|
if self.autosizing.width or self.autosizing.height then
|
||||||
|
if self.autosizing.width then
|
||||||
|
local contentWidth = self:calculateAutoWidth()
|
||||||
|
self._borderBoxWidth = contentWidth + self.padding.left + self.padding.right
|
||||||
|
self.width = contentWidth
|
||||||
|
end
|
||||||
|
if self.autosizing.height then
|
||||||
|
local contentHeight = self:calculateAutoHeight()
|
||||||
|
self._borderBoxHeight = contentHeight + self.padding.top + self.padding.bottom
|
||||||
|
self.height = contentHeight
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Re-layout children after removal
|
||||||
|
if not self._deps.Context._immediateMode then
|
||||||
|
self:layoutChildren()
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove all children from this element
|
||||||
|
function Element:clearChildren()
|
||||||
|
-- Clear parent references for all children
|
||||||
|
for _, child in ipairs(self.children) do
|
||||||
|
child.parent = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clear the children table
|
||||||
|
self.children = {}
|
||||||
|
|
||||||
|
-- Recalculate auto-sizing if needed
|
||||||
|
if self.autosizing.width or self.autosizing.height then
|
||||||
|
if self.autosizing.width then
|
||||||
|
local contentWidth = self:calculateAutoWidth()
|
||||||
|
self._borderBoxWidth = contentWidth + self.padding.left + self.padding.right
|
||||||
|
self.width = contentWidth
|
||||||
|
end
|
||||||
|
if self.autosizing.height then
|
||||||
|
local contentHeight = self:calculateAutoHeight()
|
||||||
|
self._borderBoxHeight = contentHeight + self.padding.top + self.padding.bottom
|
||||||
|
self.height = contentHeight
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Re-layout (though there are no children now)
|
||||||
|
if not self._deps.Context._immediateMode then
|
||||||
|
self:layoutChildren()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the number of children this element has
|
||||||
|
---@return number
|
||||||
|
function Element:getChildCount()
|
||||||
|
return #self.children
|
||||||
|
end
|
||||||
|
|
||||||
--- Apply positioning offsets (top, right, bottom, left) to an element
|
--- Apply positioning offsets (top, right, bottom, left) to an element
|
||||||
-- @param element The element to apply offsets to
|
-- @param element The element to apply offsets to
|
||||||
function Element:applyPositioningOffsets(element)
|
function Element:applyPositioningOffsets(element)
|
||||||
|
|||||||
@@ -1,186 +0,0 @@
|
|||||||
-- Test that demonstrates dependency injection with mocked dependencies
|
|
||||||
package.path = package.path .. ";../../?.lua;../?.lua"
|
|
||||||
local luaunit = require("testing.luaunit")
|
|
||||||
local Element = require("modules.Element")
|
|
||||||
|
|
||||||
-- Mock dependencies
|
|
||||||
local function createMockDeps()
|
|
||||||
return {
|
|
||||||
Context = {
|
|
||||||
_immediateMode = false,
|
|
||||||
defaultTheme = "test",
|
|
||||||
scaleFactors = { x = 1, y = 1 },
|
|
||||||
registerElement = function() end,
|
|
||||||
topElements = {},
|
|
||||||
},
|
|
||||||
Theme = {
|
|
||||||
Manager = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
getThemeState = function() return "normal" end,
|
|
||||||
update = function() end,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Color = {
|
|
||||||
new = function(r, g, b, a)
|
|
||||||
return { r = r or 0, g = g or 0, b = b or 0, a = a or 1 }
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
Units = {
|
|
||||||
getViewport = function() return 1920, 1080 end,
|
|
||||||
parse = function(value)
|
|
||||||
if type(value) == "number" then
|
|
||||||
return value, "px"
|
|
||||||
end
|
|
||||||
return 100, "px"
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
Blur = {},
|
|
||||||
ImageRenderer = {},
|
|
||||||
NinePatch = {},
|
|
||||||
RoundedRect = {},
|
|
||||||
ImageCache = {},
|
|
||||||
utils = {
|
|
||||||
enums = {
|
|
||||||
Positioning = { RELATIVE = "relative", ABSOLUTE = "absolute", FLEX = "flex", GRID = "grid" },
|
|
||||||
FlexDirection = { HORIZONTAL = "horizontal", VERTICAL = "vertical" },
|
|
||||||
JustifyContent = { FLEX_START = "flex-start", FLEX_END = "flex-end", CENTER = "center" },
|
|
||||||
AlignContent = { STRETCH = "stretch", FLEX_START = "flex-start", FLEX_END = "flex-end" },
|
|
||||||
AlignItems = { STRETCH = "stretch", FLEX_START = "flex-start", FLEX_END = "flex-end", CENTER = "center" },
|
|
||||||
TextAlign = { LEFT = "left", CENTER = "center", RIGHT = "right" },
|
|
||||||
AlignSelf = { AUTO = "auto", STRETCH = "stretch", FLEX_START = "flex-start" },
|
|
||||||
JustifySelf = { AUTO = "auto", FLEX_START = "flex-start", FLEX_END = "flex-end" },
|
|
||||||
FlexWrap = { NOWRAP = "nowrap", WRAP = "wrap" },
|
|
||||||
},
|
|
||||||
validateEnum = function() end,
|
|
||||||
validateRange = function() end,
|
|
||||||
validateType = function() end,
|
|
||||||
resolveTextSizePreset = function(size) return size end,
|
|
||||||
getModifiers = function() return false, false, false, false end,
|
|
||||||
},
|
|
||||||
Grid = {},
|
|
||||||
InputEvent = {
|
|
||||||
new = function() return {} end,
|
|
||||||
},
|
|
||||||
StateManager = {
|
|
||||||
generateID = function() return "test-id" end,
|
|
||||||
},
|
|
||||||
TextEditor = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
initialize = function() end,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
LayoutEngine = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
initialize = function() end,
|
|
||||||
calculateLayout = function() end,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
Renderer = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
initialize = function() end,
|
|
||||||
draw = function() end,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
EventHandler = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
initialize = function() end,
|
|
||||||
getState = function() return {} end,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
ScrollManager = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
initialize = function() end,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
ErrorHandler = {
|
|
||||||
handle = function() end,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
TestDependencyInjection = {}
|
|
||||||
|
|
||||||
function TestDependencyInjection:test_element_with_mocked_dependencies()
|
|
||||||
-- Create mock dependencies
|
|
||||||
local mockDeps = createMockDeps()
|
|
||||||
|
|
||||||
-- Track if Context.registerElement was called
|
|
||||||
local registerCalled = false
|
|
||||||
mockDeps.Context.registerElement = function()
|
|
||||||
registerCalled = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create element with mocked dependencies
|
|
||||||
local element = Element.new({
|
|
||||||
id = "test-element",
|
|
||||||
width = 100,
|
|
||||||
height = 100,
|
|
||||||
x = 0,
|
|
||||||
y = 0,
|
|
||||||
}, mockDeps)
|
|
||||||
|
|
||||||
-- Verify element was created
|
|
||||||
luaunit.assertNotNil(element)
|
|
||||||
luaunit.assertEquals(element.id, "test-element")
|
|
||||||
luaunit.assertEquals(element.width, 100)
|
|
||||||
luaunit.assertEquals(element.height, 100)
|
|
||||||
|
|
||||||
-- Verify the element is using our mocked dependencies
|
|
||||||
luaunit.assertEquals(element._deps, mockDeps)
|
|
||||||
|
|
||||||
-- Verify Context.registerElement was called
|
|
||||||
luaunit.assertTrue(registerCalled)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestDependencyInjection:test_element_without_deps_should_error()
|
|
||||||
-- Element.new now requires deps parameter
|
|
||||||
local success, err = pcall(function()
|
|
||||||
Element.new({
|
|
||||||
id = "test-element",
|
|
||||||
width = 100,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
end)
|
|
||||||
|
|
||||||
luaunit.assertFalse(success)
|
|
||||||
luaunit.assertNotNil(err)
|
|
||||||
luaunit.assertStrContains(err, "deps")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestDependencyInjection:test_can_mock_specific_module_behavior()
|
|
||||||
local mockDeps = createMockDeps()
|
|
||||||
|
|
||||||
-- Mock Units.parse to return specific values
|
|
||||||
local parseCallCount = 0
|
|
||||||
mockDeps.Units.parse = function(value)
|
|
||||||
parseCallCount = parseCallCount + 1
|
|
||||||
return 200, "px" -- Always return 200px
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create element (this will call Units.parse)
|
|
||||||
local element = Element.new({
|
|
||||||
id = "test",
|
|
||||||
width = "50%", -- This should be parsed by our mock
|
|
||||||
height = 100,
|
|
||||||
x = 0,
|
|
||||||
y = 0,
|
|
||||||
}, mockDeps)
|
|
||||||
|
|
||||||
-- Verify our mock was called
|
|
||||||
luaunit.assertTrue(parseCallCount > 0, "Units.parse should have been called")
|
|
||||||
end
|
|
||||||
|
|
||||||
os.exit(luaunit.LuaUnit.run())
|
|
||||||
@@ -396,11 +396,6 @@ function TestElementFlex:test_element_with_gap()
|
|||||||
luaunit.assertEquals(element.gap, 10)
|
luaunit.assertEquals(element.gap, 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run tests if this file is executed directly
|
|
||||||
if not _G.RUNNING_ALL_TESTS then
|
|
||||||
os.exit(luaunit.LuaUnit.run())
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for Element styling properties
|
-- Test suite for Element styling properties
|
||||||
TestElementStyling = {}
|
TestElementStyling = {}
|
||||||
|
|
||||||
@@ -532,4 +527,703 @@ function TestElementMethods:test_element_addChild()
|
|||||||
luaunit.assertEquals(parent.children[1], child)
|
luaunit.assertEquals(parent.children[1], child)
|
||||||
luaunit.assertEquals(child.parent, parent)
|
luaunit.assertEquals(child.parent, parent)
|
||||||
end
|
end
|
||||||
|
-- Test suite for scroll-related functions
|
||||||
|
TestElementScroll = {}
|
||||||
|
|
||||||
|
function TestElementScroll:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollable_element_with_overflow()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertNotNil(element)
|
||||||
|
luaunit.assertEquals(element.overflow, "scroll")
|
||||||
|
luaunit.assertNotNil(element._scrollManager)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_setScrollPosition()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
element:setScrollPosition(50, 100)
|
||||||
|
local scrollX, scrollY = element:getScrollPosition()
|
||||||
|
|
||||||
|
-- Note: actual scroll may be clamped based on content
|
||||||
|
luaunit.assertNotNil(scrollX)
|
||||||
|
luaunit.assertNotNil(scrollY)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollBy()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
local initialX, initialY = element:getScrollPosition()
|
||||||
|
element:scrollBy(10, 20)
|
||||||
|
local newX, newY = element:getScrollPosition()
|
||||||
|
|
||||||
|
luaunit.assertNotNil(newX)
|
||||||
|
luaunit.assertNotNil(newY)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollToTop()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
element:scrollToTop()
|
||||||
|
local _, scrollY = element:getScrollPosition()
|
||||||
|
luaunit.assertEquals(scrollY, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollToBottom()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
element:scrollToBottom()
|
||||||
|
-- Bottom position depends on content, just verify it doesn't error
|
||||||
|
local _, scrollY = element:getScrollPosition()
|
||||||
|
luaunit.assertNotNil(scrollY)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollToLeft()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
element:scrollToLeft()
|
||||||
|
local scrollX, _ = element:getScrollPosition()
|
||||||
|
luaunit.assertEquals(scrollX, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_scrollToRight()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
element:scrollToRight()
|
||||||
|
local scrollX, _ = element:getScrollPosition()
|
||||||
|
luaunit.assertNotNil(scrollX)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_getMaxScroll()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
local maxX, maxY = element:getMaxScroll()
|
||||||
|
luaunit.assertNotNil(maxX)
|
||||||
|
luaunit.assertNotNil(maxY)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_getScrollPercentage()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
local percentX, percentY = element:getScrollPercentage()
|
||||||
|
luaunit.assertNotNil(percentX)
|
||||||
|
luaunit.assertNotNil(percentY)
|
||||||
|
luaunit.assertTrue(percentX >= 0 and percentX <= 1)
|
||||||
|
luaunit.assertTrue(percentY >= 0 and percentY <= 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_hasOverflow()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
local hasOverflowX, hasOverflowY = element:hasOverflow()
|
||||||
|
luaunit.assertNotNil(hasOverflowX)
|
||||||
|
luaunit.assertNotNil(hasOverflowY)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementScroll:test_getContentSize()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "scrollable",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200,
|
||||||
|
overflow = "scroll"
|
||||||
|
})
|
||||||
|
|
||||||
|
local contentWidth, contentHeight = element:getContentSize()
|
||||||
|
luaunit.assertNotNil(contentWidth)
|
||||||
|
luaunit.assertNotNil(contentHeight)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for element geometry and bounds
|
||||||
|
TestElementGeometry = {}
|
||||||
|
|
||||||
|
function TestElementGeometry:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getBounds()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 10,
|
||||||
|
y = 20,
|
||||||
|
width = 100,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
local bounds = element:getBounds()
|
||||||
|
luaunit.assertEquals(bounds.x, 10)
|
||||||
|
luaunit.assertEquals(bounds.y, 20)
|
||||||
|
luaunit.assertEquals(bounds.width, 100)
|
||||||
|
luaunit.assertEquals(bounds.height, 50)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_contains_point_inside()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 10,
|
||||||
|
y = 20,
|
||||||
|
width = 100,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertTrue(element:contains(50, 40))
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_contains_point_outside()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 10,
|
||||||
|
y = 20,
|
||||||
|
width = 100,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertFalse(element:contains(200, 200))
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getBorderBoxWidth_no_border()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
local borderBoxWidth = element:getBorderBoxWidth()
|
||||||
|
luaunit.assertEquals(borderBoxWidth, 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getBorderBoxHeight_no_border()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
local borderBoxHeight = element:getBorderBoxHeight()
|
||||||
|
luaunit.assertEquals(borderBoxHeight, 50)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getBorderBoxWidth_with_border()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 50,
|
||||||
|
border = { left = 2, right = 2, top = 0, bottom = 0 }
|
||||||
|
})
|
||||||
|
|
||||||
|
local borderBoxWidth = element:getBorderBoxWidth()
|
||||||
|
-- Width includes left + right borders
|
||||||
|
luaunit.assertTrue(borderBoxWidth >= 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getAvailableContentWidth()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 100,
|
||||||
|
padding = { top = 10, right = 10, bottom = 10, left = 10 }
|
||||||
|
})
|
||||||
|
|
||||||
|
local availWidth = element:getAvailableContentWidth()
|
||||||
|
luaunit.assertNotNil(availWidth)
|
||||||
|
-- Should be less than total width due to padding
|
||||||
|
luaunit.assertTrue(availWidth <= 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getAvailableContentHeight()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 100,
|
||||||
|
padding = { top = 10, right = 10, bottom = 10, left = 10 }
|
||||||
|
})
|
||||||
|
|
||||||
|
local availHeight = element:getAvailableContentHeight()
|
||||||
|
luaunit.assertNotNil(availHeight)
|
||||||
|
-- Should be less than total height due to padding
|
||||||
|
luaunit.assertTrue(availHeight <= 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementGeometry:test_getScaledContentPadding()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 100,
|
||||||
|
padding = { top = 10, right = 10, bottom = 10, left = 10 }
|
||||||
|
})
|
||||||
|
|
||||||
|
local padding = element:getScaledContentPadding()
|
||||||
|
-- May be nil if no theme component with contentPadding
|
||||||
|
if padding then
|
||||||
|
luaunit.assertNotNil(padding.top)
|
||||||
|
luaunit.assertNotNil(padding.right)
|
||||||
|
luaunit.assertNotNil(padding.bottom)
|
||||||
|
luaunit.assertNotNil(padding.left)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for child management
|
||||||
|
TestElementChildren = {}
|
||||||
|
|
||||||
|
function TestElementChildren:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementChildren:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementChildren:test_addChild()
|
||||||
|
local parent = FlexLove.new({
|
||||||
|
id = "parent",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200
|
||||||
|
})
|
||||||
|
|
||||||
|
local child = FlexLove.new({
|
||||||
|
id = "child",
|
||||||
|
x = 10,
|
||||||
|
y = 10,
|
||||||
|
width = 50,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
parent:addChild(child)
|
||||||
|
luaunit.assertEquals(#parent.children, 1)
|
||||||
|
luaunit.assertEquals(parent.children[1], child)
|
||||||
|
luaunit.assertEquals(child.parent, parent)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementChildren:test_removeChild()
|
||||||
|
local parent = FlexLove.new({
|
||||||
|
id = "parent",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200
|
||||||
|
})
|
||||||
|
|
||||||
|
local child = FlexLove.new({
|
||||||
|
id = "child",
|
||||||
|
x = 10,
|
||||||
|
y = 10,
|
||||||
|
width = 50,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
parent:addChild(child)
|
||||||
|
parent:removeChild(child)
|
||||||
|
|
||||||
|
luaunit.assertEquals(#parent.children, 0)
|
||||||
|
luaunit.assertNil(child.parent)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementChildren:test_clearChildren()
|
||||||
|
local parent = FlexLove.new({
|
||||||
|
id = "parent",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200
|
||||||
|
})
|
||||||
|
|
||||||
|
local child1 = FlexLove.new({ id = "child1", x = 0, y = 0, width = 50, height = 50 })
|
||||||
|
local child2 = FlexLove.new({ id = "child2", x = 0, y = 0, width = 50, height = 50 })
|
||||||
|
|
||||||
|
parent:addChild(child1)
|
||||||
|
parent:addChild(child2)
|
||||||
|
parent:clearChildren()
|
||||||
|
|
||||||
|
luaunit.assertEquals(#parent.children, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementChildren:test_getChildCount()
|
||||||
|
local parent = FlexLove.new({
|
||||||
|
id = "parent",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200
|
||||||
|
})
|
||||||
|
|
||||||
|
local child1 = FlexLove.new({ id = "child1", x = 0, y = 0, width = 50, height = 50 })
|
||||||
|
local child2 = FlexLove.new({ id = "child2", x = 0, y = 0, width = 50, height = 50 })
|
||||||
|
|
||||||
|
parent:addChild(child1)
|
||||||
|
parent:addChild(child2)
|
||||||
|
|
||||||
|
luaunit.assertEquals(parent:getChildCount(), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for element visibility and opacity
|
||||||
|
TestElementVisibility = {}
|
||||||
|
|
||||||
|
function TestElementVisibility:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementVisibility:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementVisibility:test_visibility_visible()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
visibility = "visible"
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.visibility, "visible")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementVisibility:test_visibility_hidden()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
visibility = "hidden"
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.visibility, "hidden")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementVisibility:test_opacity_default()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.opacity, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementVisibility:test_opacity_custom()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
opacity = 0.5
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.opacity, 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for text editing
|
||||||
|
TestElementTextEditing = {}
|
||||||
|
|
||||||
|
function TestElementTextEditing:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementTextEditing:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementTextEditing:test_editable_element()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "input",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 40,
|
||||||
|
editable = true,
|
||||||
|
text = "Edit me"
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertTrue(element.editable)
|
||||||
|
luaunit.assertNotNil(element._textEditor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementTextEditing:test_placeholder_text()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "input",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 40,
|
||||||
|
editable = true,
|
||||||
|
placeholder = "Enter text..."
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.placeholder, "Enter text...")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for additional element features
|
||||||
|
TestElementAdditional = {}
|
||||||
|
|
||||||
|
function TestElementAdditional:setUp()
|
||||||
|
FlexLove.beginFrame(1920, 1080)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:tearDown()
|
||||||
|
FlexLove.endFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_z_index()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
z = 10
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.z, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_text()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
text = "Hello World"
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.text, "Hello World")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_text_color()
|
||||||
|
local Color = require("modules.Color")
|
||||||
|
local textColor = Color.new(255, 0, 0, 1)
|
||||||
|
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
text = "Red text",
|
||||||
|
textColor = textColor
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.textColor, textColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_background_color()
|
||||||
|
local Color = require("modules.Color")
|
||||||
|
local bgColor = Color.new(0, 0, 255, 1)
|
||||||
|
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
backgroundColor = bgColor
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.backgroundColor, bgColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_corner_radius()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
cornerRadius = 10
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertNotNil(element.cornerRadius)
|
||||||
|
luaunit.assertEquals(element.cornerRadius.topLeft, 10)
|
||||||
|
luaunit.assertEquals(element.cornerRadius.topRight, 10)
|
||||||
|
luaunit.assertEquals(element.cornerRadius.bottomLeft, 10)
|
||||||
|
luaunit.assertEquals(element.cornerRadius.bottomRight, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_margin()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
margin = { top = 5, right = 10, bottom = 5, left = 10 }
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertNotNil(element.margin)
|
||||||
|
luaunit.assertEquals(element.margin.top, 5)
|
||||||
|
luaunit.assertEquals(element.margin.right, 10)
|
||||||
|
luaunit.assertEquals(element.margin.bottom, 5)
|
||||||
|
luaunit.assertEquals(element.margin.left, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_destroy()
|
||||||
|
local parent = FlexLove.new({
|
||||||
|
id = "parent",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 200,
|
||||||
|
height = 200
|
||||||
|
})
|
||||||
|
|
||||||
|
local child = FlexLove.new({
|
||||||
|
id = "child",
|
||||||
|
parent = parent,
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 50,
|
||||||
|
height = 50
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(#parent.children, 1)
|
||||||
|
child:destroy()
|
||||||
|
luaunit.assertNil(child.parent)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_disabled()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
disabled = true
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertTrue(element.disabled)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_active()
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
active = true
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertTrue(element.active)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestElementAdditional:test_element_with_userdata()
|
||||||
|
local customData = { foo = "bar", count = 42 }
|
||||||
|
|
||||||
|
local element = FlexLove.new({
|
||||||
|
id = "test",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
userdata = customData
|
||||||
|
})
|
||||||
|
|
||||||
|
luaunit.assertEquals(element.userdata, customData)
|
||||||
|
luaunit.assertEquals(element.userdata.foo, "bar")
|
||||||
|
luaunit.assertEquals(element.userdata.count, 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if not _G.RUNNING_ALL_TESTS then
|
||||||
|
os.exit(luaunit.LuaUnit.run())
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,441 +0,0 @@
|
|||||||
-- Integration tests for LayoutEngine.lua
|
|
||||||
-- Tests actual layout calculations with mock element structures
|
|
||||||
|
|
||||||
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
|
||||||
|
|
||||||
-- Load love stub before anything else
|
|
||||||
require("testing.loveStub")
|
|
||||||
|
|
||||||
local luaunit = require("testing.luaunit")
|
|
||||||
local LayoutEngine = require("modules.LayoutEngine")
|
|
||||||
local Units = require("modules.Units")
|
|
||||||
local utils = require("modules.utils")
|
|
||||||
|
|
||||||
-- Mock dependencies
|
|
||||||
local mockContext = {
|
|
||||||
getScaleFactors = function()
|
|
||||||
return 1, 1
|
|
||||||
end,
|
|
||||||
baseScale = 1,
|
|
||||||
_cachedViewport = { width = 1920, height = 1080 },
|
|
||||||
}
|
|
||||||
|
|
||||||
local mockErrorHandler = {
|
|
||||||
error = function(module, msg) end,
|
|
||||||
warn = function(module, msg) end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local mockGrid = {
|
|
||||||
layoutGridItems = function(element) end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local deps = {
|
|
||||||
utils = utils,
|
|
||||||
Grid = mockGrid,
|
|
||||||
Units = Units,
|
|
||||||
Context = mockContext,
|
|
||||||
ErrorHandler = mockErrorHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Helper function to create mock element
|
|
||||||
local function createMockElement(props)
|
|
||||||
return {
|
|
||||||
id = props.id or "mock",
|
|
||||||
x = props.x or 0,
|
|
||||||
y = props.y or 0,
|
|
||||||
width = props.width or 100,
|
|
||||||
height = props.height or 100,
|
|
||||||
absoluteX = props.absoluteX or 0,
|
|
||||||
absoluteY = props.absoluteY or 0,
|
|
||||||
marginLeft = props.marginLeft or 0,
|
|
||||||
marginTop = props.marginTop or 0,
|
|
||||||
marginRight = props.marginRight or 0,
|
|
||||||
marginBottom = props.marginBottom or 0,
|
|
||||||
children = props.children or {},
|
|
||||||
parent = props.parent,
|
|
||||||
isHidden = props.isHidden or false,
|
|
||||||
flexGrow = props.flexGrow or 0,
|
|
||||||
flexShrink = props.flexShrink or 1,
|
|
||||||
flexBasis = props.flexBasis or "auto",
|
|
||||||
alignSelf = props.alignSelf,
|
|
||||||
minWidth = props.minWidth,
|
|
||||||
maxWidth = props.maxWidth,
|
|
||||||
minHeight = props.minHeight,
|
|
||||||
maxHeight = props.maxHeight,
|
|
||||||
text = props.text,
|
|
||||||
_layout = nil,
|
|
||||||
recalculateUnits = function() end,
|
|
||||||
layoutChildren = function() end,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for layoutChildren with flex layout
|
|
||||||
TestLayoutChildrenFlex = {}
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_horizontal_flex_start()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = utils.enums.JustifyContent.FLEX_START,
|
|
||||||
alignItems = utils.enums.AlignItems.FLEX_START,
|
|
||||||
gap = 10,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child2 = createMockElement({
|
|
||||||
id = "child2",
|
|
||||||
width = 60,
|
|
||||||
height = 40,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1, child2 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Verify layout was calculated (children positions should be set)
|
|
||||||
-- Child1 should be at (0, 0)
|
|
||||||
luaunit.assertEquals(child1.x, 0)
|
|
||||||
luaunit.assertEquals(child1.y, 0)
|
|
||||||
|
|
||||||
-- Child2 should be at (50 + gap, 0) = (60, 0)
|
|
||||||
luaunit.assertEquals(child2.x, 60)
|
|
||||||
luaunit.assertEquals(child2.y, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_vertical_flex_start()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.VERTICAL,
|
|
||||||
justifyContent = utils.enums.JustifyContent.FLEX_START,
|
|
||||||
alignItems = utils.enums.AlignItems.FLEX_START,
|
|
||||||
gap = 5,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 100,
|
|
||||||
height = 200,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child2 = createMockElement({
|
|
||||||
id = "child2",
|
|
||||||
width = 60,
|
|
||||||
height = 40,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1, child2 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Verify layout was calculated
|
|
||||||
luaunit.assertEquals(child1.x, 0)
|
|
||||||
luaunit.assertEquals(child1.y, 0)
|
|
||||||
|
|
||||||
-- Child2 should be below child1 with gap
|
|
||||||
luaunit.assertEquals(child2.x, 0)
|
|
||||||
luaunit.assertEquals(child2.y, 35) -- 30 + 5
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_with_margins()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = utils.enums.JustifyContent.FLEX_START,
|
|
||||||
gap = 0,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
marginLeft = 10,
|
|
||||||
marginRight = 5,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Child should be offset by left margin
|
|
||||||
luaunit.assertEquals(child1.x, 10)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_with_hidden_children()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.HORIZONTAL,
|
|
||||||
gap = 10,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child2 = createMockElement({
|
|
||||||
id = "child2",
|
|
||||||
width = 60,
|
|
||||||
height = 40,
|
|
||||||
isHidden = true,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child3 = createMockElement({
|
|
||||||
id = "child3",
|
|
||||||
width = 70,
|
|
||||||
height = 35,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1, child2, child3 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Child2 should be skipped, so child3 should be positioned after child1
|
|
||||||
luaunit.assertEquals(child1.x, 0)
|
|
||||||
luaunit.assertEquals(child3.x, 60) -- 50 + gap (10)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_center()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = utils.enums.JustifyContent.CENTER,
|
|
||||||
alignItems = utils.enums.AlignItems.CENTER,
|
|
||||||
gap = 10,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child2 = createMockElement({
|
|
||||||
id = "child2",
|
|
||||||
width = 60,
|
|
||||||
height = 40,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1, child2 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Children should be centered
|
|
||||||
-- Total width needed: 50 + 10 + 60 = 120
|
|
||||||
-- Remaining space: 300 - 120 = 180
|
|
||||||
-- Center offset: 180 / 2 = 90
|
|
||||||
luaunit.assertEquals(child1.x, 90)
|
|
||||||
luaunit.assertEquals(child2.x, 150) -- 90 + 50 + 10
|
|
||||||
|
|
||||||
-- Vertical centering
|
|
||||||
-- Child1 height 30, container 100, offset = (100-30)/2 = 35
|
|
||||||
luaunit.assertEquals(child1.y, 35)
|
|
||||||
-- Child2 height 40, offset = (100-40)/2 = 30
|
|
||||||
luaunit.assertEquals(child2.y, 30)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestLayoutChildrenFlex:test_layoutChildren_space_between()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
flexDirection = utils.enums.FlexDirection.HORIZONTAL,
|
|
||||||
justifyContent = utils.enums.JustifyContent.SPACE_BETWEEN,
|
|
||||||
gap = 0,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 100,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child1 = createMockElement({
|
|
||||||
id = "child1",
|
|
||||||
width = 50,
|
|
||||||
height = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child2 = createMockElement({
|
|
||||||
id = "child2",
|
|
||||||
width = 60,
|
|
||||||
height = 40,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent.children = { child1, child2 }
|
|
||||||
parent._layout = layout
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- First child at start
|
|
||||||
luaunit.assertEquals(child1.x, 0)
|
|
||||||
|
|
||||||
-- Last child at end: 300 - 60 = 240
|
|
||||||
luaunit.assertEquals(child2.x, 240)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for applyPositioningOffsets
|
|
||||||
TestApplyPositioningOffsets = {}
|
|
||||||
|
|
||||||
function TestApplyPositioningOffsets:test_applyPositioningOffsets_relative()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.FLEX,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
x = 100,
|
|
||||||
y = 50,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child = createMockElement({
|
|
||||||
id = "child",
|
|
||||||
x = 20,
|
|
||||||
y = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:applyPositioningOffsets(child)
|
|
||||||
|
|
||||||
-- Relative positioning: child keeps its x, y
|
|
||||||
luaunit.assertEquals(child.x, 20)
|
|
||||||
luaunit.assertEquals(child.y, 30)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestApplyPositioningOffsets:test_applyPositioningOffsets_absolute()
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.ABSOLUTE,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, deps)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
absoluteX = 100,
|
|
||||||
absoluteY = 50,
|
|
||||||
width = 300,
|
|
||||||
height = 200,
|
|
||||||
})
|
|
||||||
|
|
||||||
local child = createMockElement({
|
|
||||||
id = "child",
|
|
||||||
x = 20,
|
|
||||||
y = 30,
|
|
||||||
parent = parent,
|
|
||||||
})
|
|
||||||
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:applyPositioningOffsets(child)
|
|
||||||
|
|
||||||
-- Absolute positioning: child.x, child.y are relative to parent
|
|
||||||
luaunit.assertEquals(child.absoluteX, 120) -- 100 + 20
|
|
||||||
luaunit.assertEquals(child.absoluteY, 80) -- 50 + 30
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for grid layout
|
|
||||||
TestLayoutChildrenGrid = {}
|
|
||||||
|
|
||||||
function TestLayoutChildrenGrid:test_layoutChildren_grid_delegates_to_Grid()
|
|
||||||
local gridCalled = false
|
|
||||||
local mockGridForTest = {
|
|
||||||
layoutGridItems = function(element)
|
|
||||||
gridCalled = true
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local depsWithMockGrid = {
|
|
||||||
utils = utils,
|
|
||||||
Grid = mockGridForTest,
|
|
||||||
Units = Units,
|
|
||||||
Context = mockContext,
|
|
||||||
ErrorHandler = mockErrorHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
local props = {
|
|
||||||
positioning = utils.enums.Positioning.GRID,
|
|
||||||
gridRows = 2,
|
|
||||||
gridColumns = 2,
|
|
||||||
}
|
|
||||||
local layout = LayoutEngine.new(props, depsWithMockGrid)
|
|
||||||
|
|
||||||
local parent = createMockElement({
|
|
||||||
id = "parent",
|
|
||||||
width = 300,
|
|
||||||
height = 200,
|
|
||||||
})
|
|
||||||
|
|
||||||
parent._layout = layout
|
|
||||||
layout:initialize(parent)
|
|
||||||
layout:layoutChildren()
|
|
||||||
|
|
||||||
-- Verify Grid.layoutGridItems was called
|
|
||||||
luaunit.assertTrue(gridCalled)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run tests if this file is executed directly
|
|
||||||
if not _G.RUNNING_ALL_TESTS then
|
|
||||||
os.exit(luaunit.LuaUnit.run())
|
|
||||||
end
|
|
||||||
@@ -655,7 +655,69 @@ function TestLayoutEngineEdgeCases:testAutoWidthWithTextAndChildren()
|
|||||||
luaunit.assertEquals(width, 150)
|
luaunit.assertEquals(width, 150)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run tests if not running as part of a suite
|
local Units = require("modules.Units")
|
||||||
|
local utils = require("modules.utils")
|
||||||
|
|
||||||
|
-- Mock dependencies
|
||||||
|
local mockContext = {
|
||||||
|
getScaleFactors = function()
|
||||||
|
return 1, 1
|
||||||
|
end,
|
||||||
|
baseScale = 1,
|
||||||
|
_cachedViewport = { width = 1920, height = 1080 },
|
||||||
|
}
|
||||||
|
|
||||||
|
local mockErrorHandler = {
|
||||||
|
error = function(module, msg) end,
|
||||||
|
warn = function(module, msg) end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local mockGrid = {
|
||||||
|
layoutGridItems = function(element) end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local deps = {
|
||||||
|
utils = utils,
|
||||||
|
Grid = mockGrid,
|
||||||
|
Units = Units,
|
||||||
|
Context = mockContext,
|
||||||
|
ErrorHandler = mockErrorHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Helper function to create mock element
|
||||||
|
local function createMockElement(props)
|
||||||
|
return {
|
||||||
|
id = props.id or "mock",
|
||||||
|
x = props.x or 0,
|
||||||
|
y = props.y or 0,
|
||||||
|
width = props.width or 100,
|
||||||
|
height = props.height or 100,
|
||||||
|
absoluteX = props.absoluteX or 0,
|
||||||
|
absoluteY = props.absoluteY or 0,
|
||||||
|
marginLeft = props.marginLeft or 0,
|
||||||
|
marginTop = props.marginTop or 0,
|
||||||
|
marginRight = props.marginRight or 0,
|
||||||
|
marginBottom = props.marginBottom or 0,
|
||||||
|
children = props.children or {},
|
||||||
|
parent = props.parent,
|
||||||
|
isHidden = props.isHidden or false,
|
||||||
|
flexGrow = props.flexGrow or 0,
|
||||||
|
flexShrink = props.flexShrink or 1,
|
||||||
|
flexBasis = props.flexBasis or "auto",
|
||||||
|
alignSelf = props.alignSelf,
|
||||||
|
minWidth = props.minWidth,
|
||||||
|
maxWidth = props.maxWidth,
|
||||||
|
minHeight = props.minHeight,
|
||||||
|
maxHeight = props.maxHeight,
|
||||||
|
text = props.text,
|
||||||
|
_layout = nil,
|
||||||
|
recalculateUnits = function() end,
|
||||||
|
layoutChildren = function() end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- 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())
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -230,6 +230,299 @@ function TestStripNonPrintable:testStripNonPrintable_EmptyString()
|
|||||||
luaunit.assertEquals(result, "")
|
luaunit.assertEquals(result, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Mock dependencies
|
||||||
|
local mockContext = {
|
||||||
|
_immediateMode = false,
|
||||||
|
_focusedElement = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
local mockStateManager = {
|
||||||
|
getState = function()
|
||||||
|
return nil
|
||||||
|
end,
|
||||||
|
setState = function() end,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Test Suite for TextEditor Sanitization
|
||||||
|
TestTextEditorSanitization = {}
|
||||||
|
|
||||||
|
---Helper to create a TextEditor instance
|
||||||
|
function TestTextEditorSanitization:_createEditor(config)
|
||||||
|
local TextEditor = require("modules.TextEditor")
|
||||||
|
config = config or {}
|
||||||
|
local deps = {
|
||||||
|
Context = mockContext,
|
||||||
|
StateManager = mockStateManager,
|
||||||
|
Color = Color,
|
||||||
|
utils = utils,
|
||||||
|
}
|
||||||
|
return TextEditor.new(config, deps)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Sanitization Enabled Tests ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_sanitization_enabled_by_default()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
luaunit.assertTrue(editor.sanitize)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_sanitization_can_be_disabled()
|
||||||
|
local editor = self:_createEditor({ editable = true, sanitize = false })
|
||||||
|
luaunit.assertFalse(editor.sanitize)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_setText_removes_control_characters()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello\x00World\x01Test")
|
||||||
|
luaunit.assertEquals(editor:getText(), "HelloWorldTest")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_setText_preserves_valid_text()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello World! 123")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello World! 123")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_setText_removes_multiple_control_chars()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Test\x00\x01\x02\x03\x04Data")
|
||||||
|
luaunit.assertEquals(editor:getText(), "TestData")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_setText_with_sanitization_disabled()
|
||||||
|
local editor = self:_createEditor({ editable = true, sanitize = false })
|
||||||
|
editor:setText("Hello\x00World")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello\x00World")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_setText_skip_sanitization_parameter()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello\x00World", true) -- skipSanitization = true
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello\x00World")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Initial Text Sanitization ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_initial_text_is_sanitized()
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
text = "Initial\x00Text\x01",
|
||||||
|
})
|
||||||
|
luaunit.assertEquals(editor:getText(), "InitialText")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_initial_text_preserved_when_disabled()
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
sanitize = false,
|
||||||
|
text = "Initial\x00Text",
|
||||||
|
})
|
||||||
|
luaunit.assertEquals(editor:getText(), "Initial\x00Text")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === insertText Sanitization ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_insertText_sanitizes_input()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
||||||
|
editor:insertText("\x00World", 5)
|
||||||
|
luaunit.assertEquals(editor:getText(), "HelloWorld")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_insertText_with_valid_text()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
||||||
|
editor:insertText(" World", 5)
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_insertText_empty_after_sanitization()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
||||||
|
editor:insertText("\x00\x01\x02", 5) -- Only control chars
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should remain unchanged
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Length Limiting ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_maxLength_enforced_on_setText()
|
||||||
|
local editor = self:_createEditor({ editable = true, maxLength = 10 })
|
||||||
|
editor:setText("This is a very long text")
|
||||||
|
luaunit.assertEquals(#editor:getText(), 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_maxLength_enforced_on_insertText()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "12345", maxLength = 10 })
|
||||||
|
editor:insertText("67890", 5) -- This would make it exactly 10
|
||||||
|
luaunit.assertEquals(editor:getText(), "1234567890")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_maxLength_truncates_excess()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "12345", maxLength = 10 })
|
||||||
|
editor:insertText("67890EXTRA", 5) -- Would exceed limit
|
||||||
|
luaunit.assertEquals(editor:getText(), "1234567890")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_maxLength_prevents_insert_when_full()
|
||||||
|
local editor = self:_createEditor({ editable = true, text = "1234567890", maxLength = 10 })
|
||||||
|
editor:insertText("X", 10)
|
||||||
|
luaunit.assertEquals(editor:getText(), "1234567890") -- Should not change
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Newline Handling ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_newlines_allowed_in_multiline()
|
||||||
|
local editor = self:_createEditor({ editable = true, multiline = true })
|
||||||
|
editor:setText("Line1\nLine2")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Line1\nLine2")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_newlines_removed_in_singleline()
|
||||||
|
local editor = self:_createEditor({ editable = true, multiline = false })
|
||||||
|
editor:setText("Line1\nLine2")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Line1Line2")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_allowNewlines_explicit_false()
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
multiline = true,
|
||||||
|
allowNewlines = false,
|
||||||
|
})
|
||||||
|
editor:setText("Line1\nLine2")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Line1Line2")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Tab Handling ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_tabs_allowed_by_default()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello\tWorld")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello\tWorld")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_tabs_removed_when_disabled()
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
allowTabs = false,
|
||||||
|
})
|
||||||
|
editor:setText("Hello\tWorld")
|
||||||
|
luaunit.assertEquals(editor:getText(), "HelloWorld")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Custom Sanitizer ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_custom_sanitizer_used()
|
||||||
|
local customSanitizer = function(text)
|
||||||
|
return text:upper()
|
||||||
|
end
|
||||||
|
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
customSanitizer = customSanitizer,
|
||||||
|
})
|
||||||
|
editor:setText("hello world")
|
||||||
|
luaunit.assertEquals(editor:getText(), "HELLO WORLD")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_custom_sanitizer_with_control_chars()
|
||||||
|
local customSanitizer = function(text)
|
||||||
|
-- Custom sanitizer that replaces control chars with *
|
||||||
|
return text:gsub("[\x00-\x1F]", "*")
|
||||||
|
end
|
||||||
|
|
||||||
|
local editor = self:_createEditor({
|
||||||
|
editable = true,
|
||||||
|
customSanitizer = customSanitizer,
|
||||||
|
})
|
||||||
|
editor:setText("Hello\x00World\x01")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello*World*")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Unicode and Special Characters ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_unicode_preserved()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello 世界 🌍")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello 世界 🌍")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_emoji_preserved()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("😀😃😄😁")
|
||||||
|
luaunit.assertEquals(editor:getText(), "😀😃😄😁")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_special_chars_preserved()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("!@#$%^&*()_+-=[]{}|;':\",./<>?")
|
||||||
|
luaunit.assertEquals(editor:getText(), "!@#$%^&*()_+-=[]{}|;':\",./<>?")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Edge Cases ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_empty_string()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("")
|
||||||
|
luaunit.assertEquals(editor:getText(), "")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_only_control_characters()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("\x00\x01\x02\x03")
|
||||||
|
luaunit.assertEquals(editor:getText(), "")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_nil_text()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText(nil)
|
||||||
|
luaunit.assertEquals(editor:getText(), "")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_very_long_text_with_control_chars()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
local longText = string.rep("Hello\x00World", 100)
|
||||||
|
editor:setText(longText)
|
||||||
|
luaunit.assertStrContains(editor:getText(), "Hello")
|
||||||
|
luaunit.assertStrContains(editor:getText(), "World")
|
||||||
|
luaunit.assertNotStrContains(editor:getText(), "\x00")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_mixed_valid_and_invalid()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Valid\x00Text\x01With\x02Control\x03Chars")
|
||||||
|
luaunit.assertEquals(editor:getText(), "ValidTextWithControlChars")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Whitespace Handling ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_spaces_preserved()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello World")
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_leading_trailing_spaces_preserved()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText(" Hello World ")
|
||||||
|
luaunit.assertEquals(editor:getText(), " Hello World ")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- === Integration Tests ===
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_cursor_position_after_sanitization()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello")
|
||||||
|
editor:insertText("\x00World", 5)
|
||||||
|
-- Cursor should be at end of "HelloWorld" = position 10
|
||||||
|
luaunit.assertEquals(editor._cursorPosition, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestTextEditorSanitization:test_multiple_operations()
|
||||||
|
local editor = self:_createEditor({ editable = true })
|
||||||
|
editor:setText("Hello")
|
||||||
|
editor:insertText(" ", 5)
|
||||||
|
editor:insertText("World\x00", 6)
|
||||||
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
||||||
|
end
|
||||||
|
|
||||||
-- 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())
|
||||||
|
|||||||
@@ -1,308 +0,0 @@
|
|||||||
-- Import test framework
|
|
||||||
package.path = package.path .. ";./?.lua;./game/?.lua"
|
|
||||||
local luaunit = require("testing.luaunit")
|
|
||||||
|
|
||||||
-- Set up LÖVE stub environment
|
|
||||||
require("testing.loveStub")
|
|
||||||
|
|
||||||
-- Import the TextEditor module and dependencies
|
|
||||||
local utils = require("modules.utils")
|
|
||||||
local Color = require("modules.Color")
|
|
||||||
|
|
||||||
-- Mock dependencies
|
|
||||||
local mockContext = {
|
|
||||||
_immediateMode = false,
|
|
||||||
_focusedElement = nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
local mockStateManager = {
|
|
||||||
getState = function()
|
|
||||||
return nil
|
|
||||||
end,
|
|
||||||
setState = function() end,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Test Suite for TextEditor Sanitization
|
|
||||||
TestTextEditorSanitization = {}
|
|
||||||
|
|
||||||
---Helper to create a TextEditor instance
|
|
||||||
function TestTextEditorSanitization:_createEditor(config)
|
|
||||||
local TextEditor = require("modules.TextEditor")
|
|
||||||
config = config or {}
|
|
||||||
local deps = {
|
|
||||||
Context = mockContext,
|
|
||||||
StateManager = mockStateManager,
|
|
||||||
Color = Color,
|
|
||||||
utils = utils,
|
|
||||||
}
|
|
||||||
return TextEditor.new(config, deps)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Sanitization Enabled Tests ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_sanitization_enabled_by_default()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
luaunit.assertTrue(editor.sanitize)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_sanitization_can_be_disabled()
|
|
||||||
local editor = self:_createEditor({ editable = true, sanitize = false })
|
|
||||||
luaunit.assertFalse(editor.sanitize)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_setText_removes_control_characters()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello\x00World\x01Test")
|
|
||||||
luaunit.assertEquals(editor:getText(), "HelloWorldTest")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_setText_preserves_valid_text()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello World! 123")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello World! 123")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_setText_removes_multiple_control_chars()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Test\x00\x01\x02\x03\x04Data")
|
|
||||||
luaunit.assertEquals(editor:getText(), "TestData")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_setText_with_sanitization_disabled()
|
|
||||||
local editor = self:_createEditor({ editable = true, sanitize = false })
|
|
||||||
editor:setText("Hello\x00World")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello\x00World")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_setText_skip_sanitization_parameter()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello\x00World", true) -- skipSanitization = true
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello\x00World")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Initial Text Sanitization ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_initial_text_is_sanitized()
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
text = "Initial\x00Text\x01",
|
|
||||||
})
|
|
||||||
luaunit.assertEquals(editor:getText(), "InitialText")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_initial_text_preserved_when_disabled()
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
sanitize = false,
|
|
||||||
text = "Initial\x00Text",
|
|
||||||
})
|
|
||||||
luaunit.assertEquals(editor:getText(), "Initial\x00Text")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === insertText Sanitization ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_insertText_sanitizes_input()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
|
||||||
editor:insertText("\x00World", 5)
|
|
||||||
luaunit.assertEquals(editor:getText(), "HelloWorld")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_insertText_with_valid_text()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
|
||||||
editor:insertText(" World", 5)
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_insertText_empty_after_sanitization()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "Hello" })
|
|
||||||
editor:insertText("\x00\x01\x02", 5) -- Only control chars
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello") -- Should remain unchanged
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Length Limiting ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_maxLength_enforced_on_setText()
|
|
||||||
local editor = self:_createEditor({ editable = true, maxLength = 10 })
|
|
||||||
editor:setText("This is a very long text")
|
|
||||||
luaunit.assertEquals(#editor:getText(), 10)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_maxLength_enforced_on_insertText()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "12345", maxLength = 10 })
|
|
||||||
editor:insertText("67890", 5) -- This would make it exactly 10
|
|
||||||
luaunit.assertEquals(editor:getText(), "1234567890")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_maxLength_truncates_excess()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "12345", maxLength = 10 })
|
|
||||||
editor:insertText("67890EXTRA", 5) -- Would exceed limit
|
|
||||||
luaunit.assertEquals(editor:getText(), "1234567890")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_maxLength_prevents_insert_when_full()
|
|
||||||
local editor = self:_createEditor({ editable = true, text = "1234567890", maxLength = 10 })
|
|
||||||
editor:insertText("X", 10)
|
|
||||||
luaunit.assertEquals(editor:getText(), "1234567890") -- Should not change
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Newline Handling ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_newlines_allowed_in_multiline()
|
|
||||||
local editor = self:_createEditor({ editable = true, multiline = true })
|
|
||||||
editor:setText("Line1\nLine2")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Line1\nLine2")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_newlines_removed_in_singleline()
|
|
||||||
local editor = self:_createEditor({ editable = true, multiline = false })
|
|
||||||
editor:setText("Line1\nLine2")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Line1Line2")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_allowNewlines_explicit_false()
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
multiline = true,
|
|
||||||
allowNewlines = false,
|
|
||||||
})
|
|
||||||
editor:setText("Line1\nLine2")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Line1Line2")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Tab Handling ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_tabs_allowed_by_default()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello\tWorld")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello\tWorld")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_tabs_removed_when_disabled()
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
allowTabs = false,
|
|
||||||
})
|
|
||||||
editor:setText("Hello\tWorld")
|
|
||||||
luaunit.assertEquals(editor:getText(), "HelloWorld")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Custom Sanitizer ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_custom_sanitizer_used()
|
|
||||||
local customSanitizer = function(text)
|
|
||||||
return text:upper()
|
|
||||||
end
|
|
||||||
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
customSanitizer = customSanitizer,
|
|
||||||
})
|
|
||||||
editor:setText("hello world")
|
|
||||||
luaunit.assertEquals(editor:getText(), "HELLO WORLD")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_custom_sanitizer_with_control_chars()
|
|
||||||
local customSanitizer = function(text)
|
|
||||||
-- Custom sanitizer that replaces control chars with *
|
|
||||||
return text:gsub("[\x00-\x1F]", "*")
|
|
||||||
end
|
|
||||||
|
|
||||||
local editor = self:_createEditor({
|
|
||||||
editable = true,
|
|
||||||
customSanitizer = customSanitizer,
|
|
||||||
})
|
|
||||||
editor:setText("Hello\x00World\x01")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello*World*")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Unicode and Special Characters ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_unicode_preserved()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello 世界 🌍")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello 世界 🌍")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_emoji_preserved()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("😀😃😄😁")
|
|
||||||
luaunit.assertEquals(editor:getText(), "😀😃😄😁")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_special_chars_preserved()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("!@#$%^&*()_+-=[]{}|;':\",./<>?")
|
|
||||||
luaunit.assertEquals(editor:getText(), "!@#$%^&*()_+-=[]{}|;':\",./<>?")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Edge Cases ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_empty_string()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("")
|
|
||||||
luaunit.assertEquals(editor:getText(), "")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_only_control_characters()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("\x00\x01\x02\x03")
|
|
||||||
luaunit.assertEquals(editor:getText(), "")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_nil_text()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText(nil)
|
|
||||||
luaunit.assertEquals(editor:getText(), "")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_very_long_text_with_control_chars()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
local longText = string.rep("Hello\x00World", 100)
|
|
||||||
editor:setText(longText)
|
|
||||||
luaunit.assertStrContains(editor:getText(), "Hello")
|
|
||||||
luaunit.assertStrContains(editor:getText(), "World")
|
|
||||||
luaunit.assertNotStrContains(editor:getText(), "\x00")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_mixed_valid_and_invalid()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Valid\x00Text\x01With\x02Control\x03Chars")
|
|
||||||
luaunit.assertEquals(editor:getText(), "ValidTextWithControlChars")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Whitespace Handling ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_spaces_preserved()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello World")
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_leading_trailing_spaces_preserved()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText(" Hello World ")
|
|
||||||
luaunit.assertEquals(editor:getText(), " Hello World ")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Integration Tests ===
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_cursor_position_after_sanitization()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello")
|
|
||||||
editor:insertText("\x00World", 5)
|
|
||||||
-- Cursor should be at end of "HelloWorld" = position 10
|
|
||||||
luaunit.assertEquals(editor._cursorPosition, 10)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestTextEditorSanitization:test_multiple_operations()
|
|
||||||
local editor = self:_createEditor({ editable = true })
|
|
||||||
editor:setText("Hello")
|
|
||||||
editor:insertText(" ", 5)
|
|
||||||
editor:insertText("World\x00", 6)
|
|
||||||
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run tests if this file is executed directly
|
|
||||||
if not _G.RUNNING_ALL_TESTS then
|
|
||||||
os.exit(luaunit.LuaUnit.run())
|
|
||||||
end
|
|
||||||
@@ -1,302 +0,0 @@
|
|||||||
-- Test suite for Theme.lua core functionality
|
|
||||||
-- Tests theme creation, registration, and retrieval functions
|
|
||||||
|
|
||||||
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
|
||||||
|
|
||||||
-- Load love stub before anything else
|
|
||||||
require("testing.loveStub")
|
|
||||||
|
|
||||||
local luaunit = require("testing.luaunit")
|
|
||||||
local Theme = require("modules.Theme")
|
|
||||||
local Color = require("modules.Color")
|
|
||||||
|
|
||||||
-- Test suite for Theme.new()
|
|
||||||
TestThemeNew = {}
|
|
||||||
|
|
||||||
function TestThemeNew:setUp()
|
|
||||||
-- Clear any registered themes before each test
|
|
||||||
-- Note: We can't access the themes table directly, but we can work around it
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_minimal_theme()
|
|
||||||
local def = {
|
|
||||||
name = "Minimal Theme",
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
luaunit.assertNotNil(theme)
|
|
||||||
luaunit.assertEquals(theme.name, "Minimal Theme")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_components()
|
|
||||||
local def = {
|
|
||||||
name = "Test Theme",
|
|
||||||
components = {
|
|
||||||
button = {
|
|
||||||
atlas = "path/to/button.png",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
luaunit.assertNotNil(theme)
|
|
||||||
luaunit.assertEquals(theme.name, "Test Theme")
|
|
||||||
luaunit.assertNotNil(theme.components.button)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_colors()
|
|
||||||
local def = {
|
|
||||||
name = "Colored Theme",
|
|
||||||
colors = {
|
|
||||||
primary = Color.new(1, 0, 0, 1),
|
|
||||||
secondary = Color.new(0, 1, 0, 1),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
luaunit.assertNotNil(theme)
|
|
||||||
luaunit.assertNotNil(theme.colors.primary)
|
|
||||||
luaunit.assertNotNil(theme.colors.secondary)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_fonts()
|
|
||||||
local def = {
|
|
||||||
name = "Font Theme",
|
|
||||||
fonts = {
|
|
||||||
default = "path/to/font.ttf",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
luaunit.assertNotNil(theme)
|
|
||||||
luaunit.assertNotNil(theme.fonts.default)
|
|
||||||
luaunit.assertEquals(theme.fonts.default, "path/to/font.ttf")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_multiplier()
|
|
||||||
local def = {
|
|
||||||
name = "Multiplier Theme",
|
|
||||||
contentAutoSizingMultiplier = {
|
|
||||||
width = 1.5,
|
|
||||||
height = 2.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
luaunit.assertNotNil(theme)
|
|
||||||
luaunit.assertNotNil(theme.contentAutoSizingMultiplier)
|
|
||||||
luaunit.assertEquals(theme.contentAutoSizingMultiplier.width, 1.5)
|
|
||||||
luaunit.assertEquals(theme.contentAutoSizingMultiplier.height, 2.0)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_without_name_fails()
|
|
||||||
local def = {}
|
|
||||||
luaunit.assertErrorMsgContains("name", function()
|
|
||||||
Theme.new(def)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_nil_fails()
|
|
||||||
luaunit.assertErrorMsgContains("nil", function()
|
|
||||||
Theme.new(nil)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeNew:test_new_theme_with_non_table_fails()
|
|
||||||
luaunit.assertErrorMsgContains("table", function()
|
|
||||||
Theme.new("not a table")
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for Theme registration and retrieval
|
|
||||||
TestThemeRegistration = {}
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_setActive_with_theme_object()
|
|
||||||
local def = {
|
|
||||||
name = "Active Theme",
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
Theme.setActive(theme)
|
|
||||||
|
|
||||||
local active = Theme.getActive()
|
|
||||||
luaunit.assertNotNil(active)
|
|
||||||
luaunit.assertEquals(active.name, "Active Theme")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_getActive_returns_nil_initially()
|
|
||||||
-- This test assumes no theme is active, but other tests may have set one
|
|
||||||
-- So we'll just check that getActive returns something or nil
|
|
||||||
local active = Theme.getActive()
|
|
||||||
-- Just verify it doesn't error
|
|
||||||
luaunit.assertTrue(active == nil or type(active) == "table")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_hasActive_returns_boolean()
|
|
||||||
local hasActive = Theme.hasActive()
|
|
||||||
luaunit.assertTrue(type(hasActive) == "boolean")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_get_returns_nil_for_unregistered_theme()
|
|
||||||
-- Theme.get() looks up themes in the registered themes table
|
|
||||||
-- Themes created with Theme.new() and setActive() are not automatically registered
|
|
||||||
local def = {
|
|
||||||
name = "Unregistered Theme",
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
Theme.setActive(theme)
|
|
||||||
|
|
||||||
-- This should return nil because the theme was not loaded from a file
|
|
||||||
local retrieved = Theme.get("Unregistered Theme")
|
|
||||||
luaunit.assertNil(retrieved)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_get_returns_nil_for_nonexistent()
|
|
||||||
local retrieved = Theme.get("Nonexistent Theme 12345")
|
|
||||||
luaunit.assertNil(retrieved)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeRegistration:test_getRegisteredThemes_returns_table()
|
|
||||||
local themes = Theme.getRegisteredThemes()
|
|
||||||
luaunit.assertNotNil(themes)
|
|
||||||
luaunit.assertEquals(type(themes), "table")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for Theme.getComponent()
|
|
||||||
TestThemeComponent = {}
|
|
||||||
|
|
||||||
function TestThemeComponent:setUp()
|
|
||||||
-- Create and set an active theme with components
|
|
||||||
local def = {
|
|
||||||
name = "Component Test Theme",
|
|
||||||
components = {
|
|
||||||
button = {
|
|
||||||
atlas = "path/to/button.png",
|
|
||||||
},
|
|
||||||
panel = {
|
|
||||||
atlas = "path/to/panel.png",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.theme = Theme.new(def)
|
|
||||||
Theme.setActive(self.theme)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeComponent:test_getComponent_returns_component()
|
|
||||||
local component = Theme.getComponent("button")
|
|
||||||
luaunit.assertNotNil(component)
|
|
||||||
luaunit.assertEquals(component.atlas, "path/to/button.png")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeComponent:test_getComponent_returns_nil_for_nonexistent()
|
|
||||||
local component = Theme.getComponent("nonexistent")
|
|
||||||
luaunit.assertNil(component)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeComponent:test_getComponent_with_state()
|
|
||||||
-- Add a component with states
|
|
||||||
local def = {
|
|
||||||
name = "State Test Theme",
|
|
||||||
components = {
|
|
||||||
button = {
|
|
||||||
atlas = "path/to/button.png",
|
|
||||||
states = {
|
|
||||||
hover = {
|
|
||||||
atlas = "path/to/button_hover.png",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local theme = Theme.new(def)
|
|
||||||
Theme.setActive(theme)
|
|
||||||
|
|
||||||
local component = Theme.getComponent("button", "hover")
|
|
||||||
luaunit.assertNotNil(component)
|
|
||||||
luaunit.assertEquals(component.atlas, "path/to/button_hover.png")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for Theme.getColor()
|
|
||||||
TestThemeColor = {}
|
|
||||||
|
|
||||||
function TestThemeColor:setUp()
|
|
||||||
local def = {
|
|
||||||
name = "Color Test Theme",
|
|
||||||
colors = {
|
|
||||||
primary = Color.new(1, 0, 0, 1),
|
|
||||||
secondary = Color.new(0, 1, 0, 1),
|
|
||||||
textColor = Color.new(0.5, 0.5, 0.5, 1),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.theme = Theme.new(def)
|
|
||||||
Theme.setActive(self.theme)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getColor_returns_color()
|
|
||||||
local color = Theme.getColor("primary")
|
|
||||||
luaunit.assertNotNil(color)
|
|
||||||
luaunit.assertEquals(color.r, 1)
|
|
||||||
luaunit.assertEquals(color.g, 0)
|
|
||||||
luaunit.assertEquals(color.b, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getColor_returns_nil_for_nonexistent()
|
|
||||||
local color = Theme.getColor("nonexistent")
|
|
||||||
luaunit.assertNil(color)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getColorNames_returns_table()
|
|
||||||
local names = Theme.getColorNames()
|
|
||||||
luaunit.assertNotNil(names)
|
|
||||||
luaunit.assertEquals(type(names), "table")
|
|
||||||
-- Should contain our defined colors
|
|
||||||
luaunit.assertTrue(#names >= 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getAllColors_returns_table()
|
|
||||||
local colors = Theme.getAllColors()
|
|
||||||
luaunit.assertNotNil(colors)
|
|
||||||
luaunit.assertEquals(type(colors), "table")
|
|
||||||
luaunit.assertNotNil(colors.primary)
|
|
||||||
luaunit.assertNotNil(colors.secondary)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getColorOrDefault_returns_color()
|
|
||||||
local color = Theme.getColorOrDefault("primary", Color.new(0, 0, 0, 1))
|
|
||||||
luaunit.assertNotNil(color)
|
|
||||||
luaunit.assertEquals(color.r, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeColor:test_getColorOrDefault_returns_fallback()
|
|
||||||
local fallback = Color.new(0.1, 0.2, 0.3, 1)
|
|
||||||
local color = Theme.getColorOrDefault("nonexistent", fallback)
|
|
||||||
luaunit.assertNotNil(color)
|
|
||||||
luaunit.assertEquals(color.r, 0.1)
|
|
||||||
luaunit.assertEquals(color.g, 0.2)
|
|
||||||
luaunit.assertEquals(color.b, 0.3)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test suite for Theme.getFont()
|
|
||||||
TestThemeFont = {}
|
|
||||||
|
|
||||||
function TestThemeFont:setUp()
|
|
||||||
local def = {
|
|
||||||
name = "Font Test Theme",
|
|
||||||
fonts = {
|
|
||||||
default = "path/to/default.ttf",
|
|
||||||
heading = "path/to/heading.ttf",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.theme = Theme.new(def)
|
|
||||||
Theme.setActive(self.theme)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeFont:test_getFont_returns_font_path()
|
|
||||||
local font = Theme.getFont("default")
|
|
||||||
luaunit.assertNotNil(font)
|
|
||||||
luaunit.assertEquals(font, "path/to/default.ttf")
|
|
||||||
end
|
|
||||||
|
|
||||||
function TestThemeFont:test_getFont_returns_nil_for_nonexistent()
|
|
||||||
local font = Theme.getFont("nonexistent")
|
|
||||||
luaunit.assertNil(font)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run tests if this file is executed directly
|
|
||||||
if not _G.RUNNING_ALL_TESTS then
|
|
||||||
os.exit(luaunit.LuaUnit.run())
|
|
||||||
end
|
|
||||||
@@ -1,14 +1,301 @@
|
|||||||
-- Import test framework
|
-- Test suite for Theme.lua core functionality
|
||||||
package.path = package.path .. ";./?.lua;./game/?.lua"
|
-- Tests theme creation, registration, and retrieval functions
|
||||||
local luaunit = require("testing.luaunit")
|
|
||||||
|
|
||||||
-- Set up LÖVE stub environment
|
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
||||||
|
|
||||||
|
-- Load love stub before anything else
|
||||||
require("testing.loveStub")
|
require("testing.loveStub")
|
||||||
|
|
||||||
-- Import the Theme module
|
local luaunit = require("testing.luaunit")
|
||||||
local Theme = require("modules.Theme")
|
local Theme = require("modules.Theme")
|
||||||
local Color = require("modules.Color")
|
local Color = require("modules.Color")
|
||||||
|
|
||||||
|
-- Test suite for Theme.new()
|
||||||
|
TestThemeNew = {}
|
||||||
|
|
||||||
|
function TestThemeNew:setUp()
|
||||||
|
-- Clear any registered themes before each test
|
||||||
|
-- Note: We can't access the themes table directly, but we can work around it
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_minimal_theme()
|
||||||
|
local def = {
|
||||||
|
name = "Minimal Theme",
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
luaunit.assertNotNil(theme)
|
||||||
|
luaunit.assertEquals(theme.name, "Minimal Theme")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_components()
|
||||||
|
local def = {
|
||||||
|
name = "Test Theme",
|
||||||
|
components = {
|
||||||
|
button = {
|
||||||
|
atlas = "path/to/button.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
luaunit.assertNotNil(theme)
|
||||||
|
luaunit.assertEquals(theme.name, "Test Theme")
|
||||||
|
luaunit.assertNotNil(theme.components.button)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_colors()
|
||||||
|
local def = {
|
||||||
|
name = "Colored Theme",
|
||||||
|
colors = {
|
||||||
|
primary = Color.new(1, 0, 0, 1),
|
||||||
|
secondary = Color.new(0, 1, 0, 1),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
luaunit.assertNotNil(theme)
|
||||||
|
luaunit.assertNotNil(theme.colors.primary)
|
||||||
|
luaunit.assertNotNil(theme.colors.secondary)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_fonts()
|
||||||
|
local def = {
|
||||||
|
name = "Font Theme",
|
||||||
|
fonts = {
|
||||||
|
default = "path/to/font.ttf",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
luaunit.assertNotNil(theme)
|
||||||
|
luaunit.assertNotNil(theme.fonts.default)
|
||||||
|
luaunit.assertEquals(theme.fonts.default, "path/to/font.ttf")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_multiplier()
|
||||||
|
local def = {
|
||||||
|
name = "Multiplier Theme",
|
||||||
|
contentAutoSizingMultiplier = {
|
||||||
|
width = 1.5,
|
||||||
|
height = 2.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
luaunit.assertNotNil(theme)
|
||||||
|
luaunit.assertNotNil(theme.contentAutoSizingMultiplier)
|
||||||
|
luaunit.assertEquals(theme.contentAutoSizingMultiplier.width, 1.5)
|
||||||
|
luaunit.assertEquals(theme.contentAutoSizingMultiplier.height, 2.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_without_name_fails()
|
||||||
|
local def = {}
|
||||||
|
luaunit.assertErrorMsgContains("name", function()
|
||||||
|
Theme.new(def)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_nil_fails()
|
||||||
|
luaunit.assertErrorMsgContains("nil", function()
|
||||||
|
Theme.new(nil)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeNew:test_new_theme_with_non_table_fails()
|
||||||
|
luaunit.assertErrorMsgContains("table", function()
|
||||||
|
Theme.new("not a table")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for Theme registration and retrieval
|
||||||
|
TestThemeRegistration = {}
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_setActive_with_theme_object()
|
||||||
|
local def = {
|
||||||
|
name = "Active Theme",
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
Theme.setActive(theme)
|
||||||
|
|
||||||
|
local active = Theme.getActive()
|
||||||
|
luaunit.assertNotNil(active)
|
||||||
|
luaunit.assertEquals(active.name, "Active Theme")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_getActive_returns_nil_initially()
|
||||||
|
-- This test assumes no theme is active, but other tests may have set one
|
||||||
|
-- So we'll just check that getActive returns something or nil
|
||||||
|
local active = Theme.getActive()
|
||||||
|
-- Just verify it doesn't error
|
||||||
|
luaunit.assertTrue(active == nil or type(active) == "table")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_hasActive_returns_boolean()
|
||||||
|
local hasActive = Theme.hasActive()
|
||||||
|
luaunit.assertTrue(type(hasActive) == "boolean")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_get_returns_nil_for_unregistered_theme()
|
||||||
|
-- Theme.get() looks up themes in the registered themes table
|
||||||
|
-- Themes created with Theme.new() and setActive() are not automatically registered
|
||||||
|
local def = {
|
||||||
|
name = "Unregistered Theme",
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
Theme.setActive(theme)
|
||||||
|
|
||||||
|
-- This should return nil because the theme was not loaded from a file
|
||||||
|
local retrieved = Theme.get("Unregistered Theme")
|
||||||
|
luaunit.assertNil(retrieved)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_get_returns_nil_for_nonexistent()
|
||||||
|
local retrieved = Theme.get("Nonexistent Theme 12345")
|
||||||
|
luaunit.assertNil(retrieved)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeRegistration:test_getRegisteredThemes_returns_table()
|
||||||
|
local themes = Theme.getRegisteredThemes()
|
||||||
|
luaunit.assertNotNil(themes)
|
||||||
|
luaunit.assertEquals(type(themes), "table")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for Theme.getComponent()
|
||||||
|
TestThemeComponent = {}
|
||||||
|
|
||||||
|
function TestThemeComponent:setUp()
|
||||||
|
-- Create and set an active theme with components
|
||||||
|
local def = {
|
||||||
|
name = "Component Test Theme",
|
||||||
|
components = {
|
||||||
|
button = {
|
||||||
|
atlas = "path/to/button.png",
|
||||||
|
},
|
||||||
|
panel = {
|
||||||
|
atlas = "path/to/panel.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.theme = Theme.new(def)
|
||||||
|
Theme.setActive(self.theme)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeComponent:test_getComponent_returns_component()
|
||||||
|
local component = Theme.getComponent("button")
|
||||||
|
luaunit.assertNotNil(component)
|
||||||
|
luaunit.assertEquals(component.atlas, "path/to/button.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeComponent:test_getComponent_returns_nil_for_nonexistent()
|
||||||
|
local component = Theme.getComponent("nonexistent")
|
||||||
|
luaunit.assertNil(component)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeComponent:test_getComponent_with_state()
|
||||||
|
-- Add a component with states
|
||||||
|
local def = {
|
||||||
|
name = "State Test Theme",
|
||||||
|
components = {
|
||||||
|
button = {
|
||||||
|
atlas = "path/to/button.png",
|
||||||
|
states = {
|
||||||
|
hover = {
|
||||||
|
atlas = "path/to/button_hover.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local theme = Theme.new(def)
|
||||||
|
Theme.setActive(theme)
|
||||||
|
|
||||||
|
local component = Theme.getComponent("button", "hover")
|
||||||
|
luaunit.assertNotNil(component)
|
||||||
|
luaunit.assertEquals(component.atlas, "path/to/button_hover.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for Theme.getColor()
|
||||||
|
TestThemeColor = {}
|
||||||
|
|
||||||
|
function TestThemeColor:setUp()
|
||||||
|
local def = {
|
||||||
|
name = "Color Test Theme",
|
||||||
|
colors = {
|
||||||
|
primary = Color.new(1, 0, 0, 1),
|
||||||
|
secondary = Color.new(0, 1, 0, 1),
|
||||||
|
textColor = Color.new(0.5, 0.5, 0.5, 1),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.theme = Theme.new(def)
|
||||||
|
Theme.setActive(self.theme)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getColor_returns_color()
|
||||||
|
local color = Theme.getColor("primary")
|
||||||
|
luaunit.assertNotNil(color)
|
||||||
|
luaunit.assertEquals(color.r, 1)
|
||||||
|
luaunit.assertEquals(color.g, 0)
|
||||||
|
luaunit.assertEquals(color.b, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getColor_returns_nil_for_nonexistent()
|
||||||
|
local color = Theme.getColor("nonexistent")
|
||||||
|
luaunit.assertNil(color)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getColorNames_returns_table()
|
||||||
|
local names = Theme.getColorNames()
|
||||||
|
luaunit.assertNotNil(names)
|
||||||
|
luaunit.assertEquals(type(names), "table")
|
||||||
|
-- Should contain our defined colors
|
||||||
|
luaunit.assertTrue(#names >= 3)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getAllColors_returns_table()
|
||||||
|
local colors = Theme.getAllColors()
|
||||||
|
luaunit.assertNotNil(colors)
|
||||||
|
luaunit.assertEquals(type(colors), "table")
|
||||||
|
luaunit.assertNotNil(colors.primary)
|
||||||
|
luaunit.assertNotNil(colors.secondary)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getColorOrDefault_returns_color()
|
||||||
|
local color = Theme.getColorOrDefault("primary", Color.new(0, 0, 0, 1))
|
||||||
|
luaunit.assertNotNil(color)
|
||||||
|
luaunit.assertEquals(color.r, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeColor:test_getColorOrDefault_returns_fallback()
|
||||||
|
local fallback = Color.new(0.1, 0.2, 0.3, 1)
|
||||||
|
local color = Theme.getColorOrDefault("nonexistent", fallback)
|
||||||
|
luaunit.assertNotNil(color)
|
||||||
|
luaunit.assertEquals(color.r, 0.1)
|
||||||
|
luaunit.assertEquals(color.g, 0.2)
|
||||||
|
luaunit.assertEquals(color.b, 0.3)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Test suite for Theme.getFont()
|
||||||
|
TestThemeFont = {}
|
||||||
|
|
||||||
|
function TestThemeFont:setUp()
|
||||||
|
local def = {
|
||||||
|
name = "Font Test Theme",
|
||||||
|
fonts = {
|
||||||
|
default = "path/to/default.ttf",
|
||||||
|
heading = "path/to/heading.ttf",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.theme = Theme.new(def)
|
||||||
|
Theme.setActive(self.theme)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeFont:test_getFont_returns_font_path()
|
||||||
|
local font = Theme.getFont("default")
|
||||||
|
luaunit.assertNotNil(font)
|
||||||
|
luaunit.assertEquals(font, "path/to/default.ttf")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestThemeFont:test_getFont_returns_nil_for_nonexistent()
|
||||||
|
local font = Theme.getFont("nonexistent")
|
||||||
|
luaunit.assertNil(font)
|
||||||
|
end
|
||||||
|
|
||||||
-- Test Suite for Theme Validation
|
-- Test Suite for Theme Validation
|
||||||
TestThemeValidation = {}
|
TestThemeValidation = {}
|
||||||
|
|
||||||
@@ -21,13 +21,11 @@ local luaunit = require("testing.luaunit")
|
|||||||
-- Run all tests in the __tests__ directory
|
-- Run all tests in the __tests__ directory
|
||||||
local testFiles = {
|
local testFiles = {
|
||||||
"testing/__tests__/utils_test.lua",
|
"testing/__tests__/utils_test.lua",
|
||||||
"testing/__tests__/sanitization_test.lua",
|
|
||||||
"testing/__tests__/path_validation_test.lua",
|
|
||||||
"testing/__tests__/color_validation_test.lua",
|
|
||||||
"testing/__tests__/texteditor_sanitization_test.lua",
|
|
||||||
"testing/__tests__/theme_validation_test.lua",
|
|
||||||
"testing/__tests__/theme_core_test.lua",
|
|
||||||
"testing/__tests__/units_test.lua",
|
"testing/__tests__/units_test.lua",
|
||||||
|
"testing/__tests__/color_validation_test.lua",
|
||||||
|
"testing/__tests__/path_validation_test.lua",
|
||||||
|
"testing/__tests__/sanitization_test.lua",
|
||||||
|
"testing/__tests__/theme_test.lua",
|
||||||
"testing/__tests__/layout_engine_test.lua",
|
"testing/__tests__/layout_engine_test.lua",
|
||||||
"testing/__tests__/element_test.lua",
|
"testing/__tests__/element_test.lua",
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user