336 lines
10 KiB
Lua
336 lines
10 KiB
Lua
local luaunit = require("testing.luaunit")
|
|
require("testing.loveStub")
|
|
|
|
local NinePatchParser = require("modules.NinePatchParser")
|
|
local ImageDataReader = require("modules.ImageDataReader")
|
|
|
|
TestNinePatchParser = {}
|
|
|
|
-- Helper to create a valid 9-patch ImageData
|
|
-- Creates a simple 5x5 9-patch with a 1px stretch region in the center
|
|
local function create9PatchImageData()
|
|
local imageData = love.image.newImageData(5, 5)
|
|
|
|
-- Fill with transparent pixels (content area)
|
|
for y = 0, 4 do
|
|
for x = 0, 4 do
|
|
imageData:setPixel(x, y, 1, 1, 1, 0) -- Transparent
|
|
end
|
|
end
|
|
|
|
-- Top border: stretch markers (black pixel at x=2, which is the middle)
|
|
-- Corners at x=0 and x=4 should be transparent
|
|
imageData:setPixel(2, 0, 0, 0, 0, 1) -- Black stretch marker
|
|
|
|
-- Left border: stretch markers (black pixel at y=2, which is the middle)
|
|
imageData:setPixel(0, 2, 0, 0, 0, 1) -- Black stretch marker
|
|
|
|
-- Bottom border: content padding markers (optional, using same as stretch)
|
|
imageData:setPixel(2, 4, 0, 0, 0, 1) -- Black content marker
|
|
|
|
-- Right border: content padding markers (optional, using same as stretch)
|
|
imageData:setPixel(4, 2, 0, 0, 0, 1) -- Black content marker
|
|
|
|
return imageData
|
|
end
|
|
|
|
-- Helper to create a 9-patch with multiple stretch regions
|
|
local function create9PatchMultipleRegions()
|
|
local imageData = love.image.newImageData(7, 7)
|
|
|
|
-- Fill with transparent
|
|
for y = 0, 6 do
|
|
for x = 0, 6 do
|
|
imageData:setPixel(x, y, 1, 1, 1, 0)
|
|
end
|
|
end
|
|
|
|
-- Top: two stretch regions (x=1-2 and x=4-5)
|
|
imageData:setPixel(1, 0, 0, 0, 0, 1)
|
|
imageData:setPixel(2, 0, 0, 0, 0, 1)
|
|
imageData:setPixel(4, 0, 0, 0, 0, 1)
|
|
imageData:setPixel(5, 0, 0, 0, 0, 1)
|
|
|
|
-- Left: two stretch regions (y=1-2 and y=4-5)
|
|
imageData:setPixel(0, 1, 0, 0, 0, 1)
|
|
imageData:setPixel(0, 2, 0, 0, 0, 1)
|
|
imageData:setPixel(0, 4, 0, 0, 0, 1)
|
|
imageData:setPixel(0, 5, 0, 0, 0, 1)
|
|
|
|
return imageData
|
|
end
|
|
|
|
-- Helper to mock ImageDataReader.loadImageData for testing
|
|
local originalLoadImageData = ImageDataReader.loadImageData
|
|
local function mockImageDataReader(mockData)
|
|
ImageDataReader.loadImageData = function(path)
|
|
if path == "test_valid_9patch.png" then
|
|
return mockData
|
|
elseif path == "test_multiple_regions.png" then
|
|
return create9PatchMultipleRegions()
|
|
elseif path == "test_small_2x2.png" then
|
|
return love.image.newImageData(2, 2)
|
|
elseif path == "test_no_stretch.png" then
|
|
-- Create a 5x5 with no black pixels (invalid 9-patch)
|
|
local data = love.image.newImageData(5, 5)
|
|
for y = 0, 4 do
|
|
for x = 0, 4 do
|
|
data:setPixel(x, y, 1, 1, 1, 0)
|
|
end
|
|
end
|
|
return data
|
|
else
|
|
return originalLoadImageData(path)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function restoreImageDataReader()
|
|
ImageDataReader.loadImageData = originalLoadImageData
|
|
end
|
|
|
|
-- Unhappy path tests for NinePatchParser.parse()
|
|
|
|
function TestNinePatchParser:testParseWithNilPath()
|
|
local result, err = NinePatchParser.parse(nil)
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
luaunit.assertStrContains(err, "cannot be nil")
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithEmptyString()
|
|
local result, err = NinePatchParser.parse("")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithInvalidPath()
|
|
local result, err = NinePatchParser.parse("nonexistent/path/to/image.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
luaunit.assertStrContains(err, "Failed to load")
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithNonImageFile()
|
|
local result, err = NinePatchParser.parse("testing/runAll.lua")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithNumberInsteadOfString()
|
|
local result, err = NinePatchParser.parse(123)
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithTableInsteadOfString()
|
|
local result, err = NinePatchParser.parse({})
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithBooleanInsteadOfString()
|
|
local result, err = NinePatchParser.parse(true)
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
-- Edge case: dimensions that are too small
|
|
|
|
function TestNinePatchParser:testParseWith1x1Image()
|
|
-- Create a minimal mock - parser needs at least 3x3
|
|
-- This would fail in real scenario
|
|
luaunit.assertTrue(true) -- Placeholder for actual test with real image
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWith2x2Image()
|
|
-- Would fail - minimum is 3x3
|
|
luaunit.assertTrue(true) -- Placeholder
|
|
end
|
|
|
|
-- Test path validation
|
|
|
|
function TestNinePatchParser:testParseWithRelativePath()
|
|
local result, err = NinePatchParser.parse("./fake/path.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithAbsolutePath()
|
|
local result, err = NinePatchParser.parse("/fake/absolute/path.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithPathContainingSpaces()
|
|
local result, err = NinePatchParser.parse("path with spaces/image.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithPathContainingSpecialChars()
|
|
local result, err = NinePatchParser.parse("path/with@special#chars.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithVeryLongPath()
|
|
local longPath = string.rep("a/", 100) .. "image.png"
|
|
local result, err = NinePatchParser.parse(longPath)
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithDotDotPath()
|
|
local result, err = NinePatchParser.parse("../../../etc/passwd")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithMixedSlashes()
|
|
local result, err = NinePatchParser.parse("path\\with/mixed\\slashes.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithTrailingSlash()
|
|
local result, err = NinePatchParser.parse("path/to/image.png/")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithDoubleSlashes()
|
|
local result, err = NinePatchParser.parse("path//to//image.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithNoExtension()
|
|
local result, err = NinePatchParser.parse("path/to/image")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithWrongExtension()
|
|
local result, err = NinePatchParser.parse("path/to/image.jpg")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseWithMultipleDots()
|
|
local result, err = NinePatchParser.parse("path/to/image.9.patch.png")
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
end
|
|
|
|
-- Happy path tests with mocked ImageData
|
|
|
|
function TestNinePatchParser:testParseValidSimple9Patch()
|
|
local mockData = create9PatchImageData()
|
|
mockImageDataReader(mockData)
|
|
|
|
local result, err = NinePatchParser.parse("test_valid_9patch.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNotNil(result)
|
|
luaunit.assertNil(err)
|
|
luaunit.assertNotNil(result.insets)
|
|
luaunit.assertNotNil(result.contentPadding)
|
|
luaunit.assertNotNil(result.stretchX)
|
|
luaunit.assertNotNil(result.stretchY)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseValidMultipleRegions()
|
|
mockImageDataReader()
|
|
|
|
local result, err = NinePatchParser.parse("test_multiple_regions.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNotNil(result)
|
|
luaunit.assertNil(err)
|
|
-- Should have 2 stretch regions in each direction
|
|
luaunit.assertEquals(#result.stretchX, 2)
|
|
luaunit.assertEquals(#result.stretchY, 2)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseTooSmall2x2()
|
|
mockImageDataReader()
|
|
|
|
local result, err = NinePatchParser.parse("test_small_2x2.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
luaunit.assertStrContains(err, "Invalid 9-patch dimensions")
|
|
luaunit.assertStrContains(err, "minimum 3x3")
|
|
end
|
|
|
|
function TestNinePatchParser:testParseNoStretchRegions()
|
|
mockImageDataReader()
|
|
|
|
local result, err = NinePatchParser.parse("test_no_stretch.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNil(result)
|
|
luaunit.assertNotNil(err)
|
|
luaunit.assertStrContains(err, "No stretch regions found")
|
|
end
|
|
|
|
function TestNinePatchParser:testParseInsetsCalculation()
|
|
local mockData = create9PatchImageData()
|
|
mockImageDataReader(mockData)
|
|
|
|
local result, err = NinePatchParser.parse("test_valid_9patch.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNotNil(result)
|
|
-- Verify insets structure
|
|
luaunit.assertNotNil(result.insets.left)
|
|
luaunit.assertNotNil(result.insets.top)
|
|
luaunit.assertNotNil(result.insets.right)
|
|
luaunit.assertNotNil(result.insets.bottom)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseContentPaddingCalculation()
|
|
local mockData = create9PatchImageData()
|
|
mockImageDataReader(mockData)
|
|
|
|
local result, err = NinePatchParser.parse("test_valid_9patch.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNotNil(result)
|
|
-- Verify content padding structure
|
|
luaunit.assertNotNil(result.contentPadding.left)
|
|
luaunit.assertNotNil(result.contentPadding.top)
|
|
luaunit.assertNotNil(result.contentPadding.right)
|
|
luaunit.assertNotNil(result.contentPadding.bottom)
|
|
end
|
|
|
|
function TestNinePatchParser:testParseStretchRegionsFormat()
|
|
local mockData = create9PatchImageData()
|
|
mockImageDataReader(mockData)
|
|
|
|
local result, err = NinePatchParser.parse("test_valid_9patch.png")
|
|
|
|
restoreImageDataReader()
|
|
|
|
luaunit.assertNotNil(result)
|
|
-- Verify stretchX and stretchY are arrays of {start, end} pairs
|
|
luaunit.assertTrue(#result.stretchX >= 1)
|
|
luaunit.assertTrue(#result.stretchY >= 1)
|
|
luaunit.assertNotNil(result.stretchX[1].start)
|
|
luaunit.assertNotNil(result.stretchX[1]["end"])
|
|
luaunit.assertNotNil(result.stretchY[1].start)
|
|
luaunit.assertNotNil(result.stretchY[1]["end"])
|
|
end
|
|
|
|
if not _G.RUNNING_ALL_TESTS then
|
|
os.exit(luaunit.LuaUnit.run())
|
|
end
|