calc module
This commit is contained in:
@@ -11,6 +11,15 @@ local ErrorHandler = require("modules.ErrorHandler")
|
||||
-- Initialize ErrorHandler
|
||||
ErrorHandler.init({})
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Load FlexLove which properly initializes all dependencies
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
|
||||
232
testing/__tests__/calc_test.lua
Normal file
232
testing/__tests__/calc_test.lua
Normal file
@@ -0,0 +1,232 @@
|
||||
---@diagnostic disable: undefined-global, undefined-field
|
||||
local lu = require("testing.luaunit")
|
||||
|
||||
-- Mock love globals for testing environment
|
||||
_G.love = _G.love or {}
|
||||
_G.love.graphics = _G.love.graphics or {}
|
||||
_G.love.graphics.getDimensions = function()
|
||||
return 1920, 1080
|
||||
end
|
||||
_G.love.window = _G.love.window or {}
|
||||
_G.love.window.getMode = function()
|
||||
return 1920, 1080
|
||||
end
|
||||
|
||||
-- Load Calc module directly
|
||||
local Calc = require("modules.Calc")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
|
||||
-- Initialize with error handler
|
||||
ErrorHandler.init({})
|
||||
Calc.init({ ErrorHandler = ErrorHandler })
|
||||
|
||||
---@class TestCalc
|
||||
TestCalc = {}
|
||||
|
||||
function TestCalc:setUp()
|
||||
-- Fresh initialization for each test
|
||||
end
|
||||
|
||||
function TestCalc:tearDown()
|
||||
-- Cleanup after each test
|
||||
end
|
||||
|
||||
--- Test basic arithmetic: addition
|
||||
function TestCalc:testBasicAddition()
|
||||
local calcObj = Calc.new("100px + 50px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 150)
|
||||
end
|
||||
|
||||
--- Test basic arithmetic: subtraction
|
||||
function TestCalc:testBasicSubtraction()
|
||||
local calcObj = Calc.new("100px - 30px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 70)
|
||||
end
|
||||
|
||||
--- Test basic arithmetic: multiplication
|
||||
function TestCalc:testBasicMultiplication()
|
||||
local calcObj = Calc.new("10px * 5")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 50)
|
||||
end
|
||||
|
||||
--- Test basic arithmetic: division
|
||||
function TestCalc:testBasicDivision()
|
||||
local calcObj = Calc.new("100px / 4")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 25)
|
||||
end
|
||||
|
||||
--- Test negative numbers
|
||||
function TestCalc:testNegativeNumbers()
|
||||
local calcObj = Calc.new("-50px + 100px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 50)
|
||||
end
|
||||
|
||||
--- Test decimal numbers
|
||||
function TestCalc:testDecimalNumbers()
|
||||
local calcObj = Calc.new("10.5px + 5.5px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 16)
|
||||
end
|
||||
|
||||
--- Test percentage units
|
||||
function TestCalc:testPercentageUnits()
|
||||
local calcObj = Calc.new("50% + 25%")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, 1000, nil, nil) -- parent size = 1000
|
||||
lu.assertEquals(result, 750) -- 50% of 1000 + 25% of 1000 = 500 + 250
|
||||
end
|
||||
|
||||
--- Test viewport width units (vw)
|
||||
function TestCalc:testViewportWidthUnits()
|
||||
local calcObj = Calc.new("50vw - 10vw")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 768) -- 40% of 1920 = 768
|
||||
end
|
||||
|
||||
--- Test viewport height units (vh)
|
||||
function TestCalc:testViewportHeightUnits()
|
||||
local calcObj = Calc.new("50vh + 10vh")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 648) -- 60% of 1080 = 648
|
||||
end
|
||||
|
||||
--- Test mixed units
|
||||
function TestCalc:testMixedUnits()
|
||||
local calcObj = Calc.new("50% - 10vw")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, 1000, nil, nil)
|
||||
lu.assertEquals(result, 308) -- 50% of 1000 - 10% of 1920 = 500 - 192 = 308
|
||||
end
|
||||
|
||||
--- Test complex expression with multiple operations
|
||||
function TestCalc:testComplexExpression()
|
||||
local calcObj = Calc.new("100px + 50px - 20px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 130)
|
||||
end
|
||||
|
||||
--- Test parentheses for precedence
|
||||
function TestCalc:testParentheses()
|
||||
local calcObj = Calc.new("(100px + 50px) * 2")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 300)
|
||||
end
|
||||
|
||||
--- Test nested parentheses
|
||||
function TestCalc:testNestedParentheses()
|
||||
local calcObj = Calc.new("((100px + 50px) / 3) * 2")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 100) -- (150 / 3) * 2 = 50 * 2 = 100
|
||||
end
|
||||
|
||||
--- Test operator precedence (multiplication before addition)
|
||||
function TestCalc:testOperatorPrecedence()
|
||||
local calcObj = Calc.new("100px + 50px * 2")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 200) -- 100 + (50 * 2) = 100 + 100 = 200
|
||||
end
|
||||
|
||||
--- Test centering use case (50% - 10vw)
|
||||
function TestCalc:testCenteringUseCase()
|
||||
local calcObj = Calc.new("50% - 10vw")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
-- Assuming element width is 20vw (384px) and parent width is 1920px
|
||||
-- 50% of parent - 10vw should center it
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, 1920, nil, nil)
|
||||
lu.assertEquals(result, 768) -- 50% of 1920 - 10% of 1920 = 960 - 192 = 768
|
||||
end
|
||||
|
||||
--- Test element width units (ew)
|
||||
function TestCalc:testElementWidthUnits()
|
||||
local calcObj = Calc.new("100ew - 20ew")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, 500, nil) -- element width = 500
|
||||
lu.assertEquals(result, 400) -- 80% of 500 = 400
|
||||
end
|
||||
|
||||
--- Test element height units (eh)
|
||||
function TestCalc:testElementHeightUnits()
|
||||
local calcObj = Calc.new("50eh + 25eh")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, 300) -- element height = 300
|
||||
lu.assertEquals(result, 225) -- 75% of 300 = 225
|
||||
end
|
||||
|
||||
--- Test whitespace handling
|
||||
function TestCalc:testWhitespaceHandling()
|
||||
local calcObj = Calc.new(" 100px + 50px ")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 150)
|
||||
end
|
||||
|
||||
--- Test zero value
|
||||
function TestCalc:testZeroValue()
|
||||
local calcObj = Calc.new("100px - 100px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 0)
|
||||
end
|
||||
|
||||
--- Test single value (no operation)
|
||||
function TestCalc:testSingleValue()
|
||||
local calcObj = Calc.new("100px")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 100)
|
||||
end
|
||||
|
||||
--- Test isCalc function with non-calc values
|
||||
function TestCalc:testIsCalcWithNonCalcValues()
|
||||
lu.assertFalse(Calc.isCalc("100px"))
|
||||
lu.assertFalse(Calc.isCalc(100))
|
||||
lu.assertFalse(Calc.isCalc(nil))
|
||||
lu.assertFalse(Calc.isCalc({}))
|
||||
end
|
||||
|
||||
--- Test division by zero error handling
|
||||
function TestCalc:testDivisionByZeroHandling()
|
||||
local calcObj = Calc.new("100px / 0")
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 0) -- Should return 0 on division by zero error
|
||||
end
|
||||
|
||||
--- Test invalid expression error handling
|
||||
function TestCalc:testInvalidExpressionHandling()
|
||||
local calcObj = Calc.new("100px +") -- Incomplete expression
|
||||
lu.assertTrue(Calc.isCalc(calcObj))
|
||||
-- Should return 0 for invalid expressions
|
||||
local result = Calc.resolve(calcObj, 1920, 1080, nil, nil, nil)
|
||||
lu.assertEquals(result, 0)
|
||||
end
|
||||
|
||||
--- Test complex real-world centering scenario
|
||||
function TestCalc:testRealWorldCentering()
|
||||
-- Button with 20vw width, centered at 50% - 10vw
|
||||
local xCalc = Calc.new("50% - 10vw")
|
||||
local result = Calc.resolve(xCalc, 1920, 1080, 1920, nil, nil)
|
||||
-- Expected: 50% of 1920 - 10% of 1920 = 960 - 192 = 768
|
||||
lu.assertEquals(result, 768)
|
||||
end
|
||||
|
||||
if not _G.RUNNING_ALL_TESTS then
|
||||
os.exit(lu.LuaUnit.run())
|
||||
end
|
||||
@@ -5,6 +5,16 @@
|
||||
-- 3. Unsafe input access (nil dereference, division by zero, etc.)
|
||||
|
||||
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
||||
|
||||
-- Add custom package searcher to handle FlexLove.modules.X imports
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
require("testing.loveStub")
|
||||
local luaunit = require("testing.luaunit")
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
@@ -12,6 +12,15 @@ local ErrorHandler = require("modules.ErrorHandler")
|
||||
-- Initialize ErrorHandler
|
||||
ErrorHandler.init({})
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Load FlexLove which properly initializes all dependencies
|
||||
local FlexLove = require("FlexLove")
|
||||
local Element = require("modules.Element")
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
-- Add custom package searcher to handle FlexLove.modules.X imports
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
local luaunit = require("testing.luaunit")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
require("testing.loveStub")
|
||||
|
||||
@@ -4,6 +4,16 @@ package.path = package.path .. ";./?.lua;./modules/?.lua"
|
||||
|
||||
require("testing.loveStub")
|
||||
local luaunit = require("testing.luaunit")
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
TestGridLayout = {}
|
||||
|
||||
@@ -518,6 +518,13 @@ function TestImageRendererElementIntegration:setUp()
|
||||
local Renderer = require("modules.Renderer")
|
||||
local EventHandler = require("modules.EventHandler")
|
||||
local ImageCache = require("modules.ImageCache")
|
||||
local Context = require("modules.Context")
|
||||
local StateManager = require("modules.StateManager")
|
||||
local InputEvent = require("modules.InputEvent")
|
||||
local Theme = require("modules.Theme")
|
||||
local TextEditor = require("modules.TextEditor")
|
||||
local ScrollManager = require("modules.ScrollManager")
|
||||
local RoundedRect = require("modules.RoundedRect")
|
||||
|
||||
self.deps = {
|
||||
utils = utils,
|
||||
@@ -529,7 +536,18 @@ function TestImageRendererElementIntegration:setUp()
|
||||
ImageCache = ImageCache,
|
||||
ImageRenderer = ImageRenderer,
|
||||
ErrorHandler = ErrorHandler,
|
||||
Context = Context,
|
||||
StateManager = StateManager,
|
||||
InputEvent = InputEvent,
|
||||
Theme = Theme,
|
||||
TextEditor = TextEditor,
|
||||
ScrollManager = ScrollManager,
|
||||
RoundedRect = RoundedRect,
|
||||
}
|
||||
|
||||
-- Initialize Element with dependencies
|
||||
Element.init(self.deps)
|
||||
|
||||
self.Element = Element
|
||||
end
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ ErrorHandler.init({})
|
||||
require("testing.loveStub")
|
||||
|
||||
local ImageScaler = require("modules.ImageScaler")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
|
||||
-- Initialize ErrorHandler
|
||||
ErrorHandler.init({})
|
||||
-- Initialize ImageScaler with ErrorHandler
|
||||
ImageScaler.init({ ErrorHandler = ErrorHandler })
|
||||
|
||||
TestImageScaler = {}
|
||||
|
||||
|
||||
@@ -11,9 +11,19 @@ local luaunit = require("testing.luaunit")
|
||||
local LayoutEngine = require("modules.LayoutEngine")
|
||||
local Units = require("modules.Units")
|
||||
local utils = require("modules.utils")
|
||||
local FlexLove = require("FlexLove")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
local Animation = require("modules.Animation")
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
local Transform = Animation.Transform
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
@@ -7,6 +7,15 @@ local loveStub = require("testing.loveStub")
|
||||
-- Set up stub before requiring modules
|
||||
_G.love = loveStub
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
local Performance = require("modules.Performance")
|
||||
local Element = require('modules.Element')
|
||||
|
||||
@@ -11,6 +11,16 @@ local Theme = require("modules.Theme")
|
||||
local Blur = require("modules.Blur")
|
||||
local utils = require("modules.utils")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
|
||||
-- Setup package loader to map FlexLove.modules.X to modules/X
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
-- Initialize ErrorHandler
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
||||
|
||||
-- Add custom package searcher to handle FlexLove.modules.X imports
|
||||
local originalSearchers = package.searchers or package.loaders
|
||||
table.insert(originalSearchers, 2, function(modname)
|
||||
if modname:match("^FlexLove%.modules%.") then
|
||||
local moduleName = modname:gsub("^FlexLove%.modules%.", "")
|
||||
return function() return require("modules." .. moduleName) end
|
||||
end
|
||||
end)
|
||||
|
||||
require("testing.loveStub")
|
||||
local lu = require("testing.luaunit")
|
||||
|
||||
|
||||
@@ -9,9 +9,17 @@ require("testing.loveStub")
|
||||
local luaunit = require("testing.luaunit")
|
||||
local Units = require("modules.Units")
|
||||
local Context = require("modules.Context")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
local Calc = require("modules.Calc")
|
||||
|
||||
-- Initialize Units module with Context
|
||||
Units.init({ Context = Context })
|
||||
-- Initialize ErrorHandler
|
||||
ErrorHandler.init({})
|
||||
|
||||
-- Initialize Calc
|
||||
Calc.init({ ErrorHandler = ErrorHandler })
|
||||
|
||||
-- Initialize Units module with dependencies
|
||||
Units.init({ Context = Context, ErrorHandler = ErrorHandler, Calc = Calc })
|
||||
|
||||
-- Mock viewport dimensions for consistent tests
|
||||
local MOCK_VIEWPORT_WIDTH = 1920
|
||||
|
||||
Reference in New Issue
Block a user