mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
small update
changed tests so that all assert failures are logged rather than just the first assert that failed, added isOS() to the test method class to be used in tests directly, updated test readme on a couple bits and added newTexture basic check
This commit is contained in:
@@ -374,23 +374,42 @@ TestMethod = {
|
||||
end,
|
||||
|
||||
|
||||
-- @method - TestMethod:isOS()
|
||||
-- @desc - checks for a specific OS (or list of OSs)
|
||||
-- @param {string||table} - single OS string or list of OSs that are allowed,
|
||||
-- these will be checked agaisnt love.system.getOS()'s return value
|
||||
-- @return {boolean} - returns true if one of the OSs given matches actual OS
|
||||
isOS = function(self, oss)
|
||||
if type(oss) == 'table' then
|
||||
for o=1,#oss do
|
||||
if oss[o] == love.test.current_os then return true end
|
||||
end
|
||||
else
|
||||
return love.test.current_os == oss
|
||||
end
|
||||
end,
|
||||
|
||||
-- @method - TestMethod:evaluateTest()
|
||||
-- @desc - evaluates the results of all assertions for a final restult
|
||||
-- @return {nil}
|
||||
evaluateTest = function(self)
|
||||
local failure = ''
|
||||
local failures = 0
|
||||
|
||||
-- check all asserts for failures, additional failures are also printed
|
||||
local assert_failures = {}
|
||||
for a=1,#self.asserts do
|
||||
-- @TODO show all failed assertion methods?
|
||||
-- currently just shows the first assert that failed
|
||||
if not self.asserts[a].passed and not self.skipped then
|
||||
if failure == '' then failure = self.asserts[a] end
|
||||
table.insert(assert_failures, self.asserts[a])
|
||||
failures = failures + 1
|
||||
end
|
||||
end
|
||||
if self.fatal ~= '' then failure = self.fatal end
|
||||
local passed = tostring(#self.asserts - failures)
|
||||
local total = '(' .. passed .. '/' .. tostring(#self.asserts) .. ')'
|
||||
|
||||
-- skipped tests have a special log
|
||||
if self.skipped then
|
||||
self.testmodule.skipped = self.testmodule.skipped + 1
|
||||
love.test.totals[3] = love.test.totals[3] + 1
|
||||
@@ -398,9 +417,12 @@ TestMethod = {
|
||||
total = '',
|
||||
result = "SKIP",
|
||||
passed = false,
|
||||
message = '(0/0) - method skipped [' .. self.skipreason .. ']'
|
||||
message = '(0/0) - method skipped [' .. self.skipreason .. ']',
|
||||
failures = {}
|
||||
}
|
||||
else
|
||||
|
||||
-- if no failure but has asserts, then passed
|
||||
if failure == '' and #self.asserts > 0 then
|
||||
self.passed = true
|
||||
self.testmodule.passed = self.testmodule.passed + 1
|
||||
@@ -409,38 +431,48 @@ TestMethod = {
|
||||
total = total,
|
||||
result = 'PASS',
|
||||
passed = true,
|
||||
message = nil
|
||||
message = nil,
|
||||
failures = {}
|
||||
}
|
||||
|
||||
-- otherwise it failed
|
||||
else
|
||||
self.passed = false
|
||||
self.testmodule.failed = self.testmodule.failed + 1
|
||||
love.test.totals[2] = love.test.totals[2] + 1
|
||||
|
||||
-- no asserts means invalid test
|
||||
if #self.asserts == 0 then
|
||||
local msg = 'no asserts defined'
|
||||
if self.fatal ~= '' then msg = self.fatal end
|
||||
self.result = {
|
||||
total = total,
|
||||
result = 'FAIL',
|
||||
passed = false,
|
||||
key = 'test',
|
||||
message = msg
|
||||
self.result = {
|
||||
total = total,
|
||||
result = 'FAIL',
|
||||
passed = false,
|
||||
key = 'test',
|
||||
message = msg,
|
||||
failures = {}
|
||||
}
|
||||
|
||||
-- otherwise we had failures, log the first and supply the list of
|
||||
-- additional failures if any for printResult()
|
||||
else
|
||||
local key = failure['key']
|
||||
if failure['test'] ~= nil then
|
||||
key = key .. ' [' .. failure['test'] .. ']'
|
||||
end
|
||||
local msg = failure['message']
|
||||
if self.fatal ~= '' then
|
||||
if self.fatal ~= '' then
|
||||
key = 'code'
|
||||
msg = self.fatal
|
||||
end
|
||||
self.result = {
|
||||
total = total,
|
||||
result = 'FAIL',
|
||||
passed = false,
|
||||
self.result = {
|
||||
total = total,
|
||||
result = 'FAIL',
|
||||
passed = false,
|
||||
key = key,
|
||||
message = msg
|
||||
message = msg,
|
||||
failures = assert_failures
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -535,6 +567,21 @@ TestMethod = {
|
||||
' ==> ' .. self.result.result .. ' - ' .. endtime .. 's ' ..
|
||||
self.result.total .. msg
|
||||
)
|
||||
|
||||
-- if we failed on multiple asserts, list them here - makes it easier for
|
||||
-- debugging new methods added that are failing multiple asserts
|
||||
if #self.result.failures > 1 then
|
||||
for f=2,#self.result.failures do
|
||||
local addf = self.result.failures[f]
|
||||
self.testmodule:log(
|
||||
self.testmodule.colors[self.result.result],
|
||||
' ' .. tested .. matching,
|
||||
' ==> ' ..
|
||||
addf['key'] .. ' [' .. addf['test'] .. '] failed - ' .. addf['message']
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ TestSuite = {
|
||||
delayed = nil,
|
||||
fakequit = false,
|
||||
windowmode = true,
|
||||
current_os = love.system.getOS(),
|
||||
|
||||
-- love modules to test
|
||||
audio = {},
|
||||
@@ -76,7 +77,10 @@ TestSuite = {
|
||||
TextRun = 'love.' .. self.module.module .. '.' .. method
|
||||
|
||||
self.test.co = coroutine.create(function()
|
||||
local ok, chunk, err = pcall(love.test[love.test.module.module][method], love.test.test)
|
||||
local ok, chunk, err = pcall(
|
||||
love.test[love.test.module.module][method],
|
||||
love.test.test
|
||||
)
|
||||
if ok == false then
|
||||
love.test.test['passed'] = false
|
||||
love.test.test['fatal'] = tostring(chunk) .. tostring(err)
|
||||
@@ -140,7 +144,14 @@ TestSuite = {
|
||||
printResult = function(self)
|
||||
local finaltime = UtilTimeFormat(self.time)
|
||||
|
||||
local name, version, vendor, device = love.graphics.getRendererInfo()
|
||||
-- in case we dont have love.graphics loaded, for future module specific disabling
|
||||
local name = 'NONE'
|
||||
local version = 'NONE'
|
||||
local vendor = 'NONE'
|
||||
local device = 'NONE'
|
||||
if love.graphics then
|
||||
name, version, vendor, device = love.graphics.getRendererInfo()
|
||||
end
|
||||
|
||||
local md = '<!-- PASSED ' .. tostring(self.totals[1]) ..
|
||||
' || FAILED ' .. tostring(self.totals[2]) ..
|
||||
|
||||
@@ -41,6 +41,8 @@ love.load = function(args)
|
||||
resizable = true,
|
||||
centered = true
|
||||
})
|
||||
|
||||
-- set up some graphics to draw if enabled
|
||||
if love.graphics ~= nil then
|
||||
love.graphics.setDefaultFilter("nearest", "nearest")
|
||||
love.graphics.setLineStyle('rough')
|
||||
@@ -54,6 +56,7 @@ love.load = function(args)
|
||||
TextCommand = 'Loading...'
|
||||
TextRun = ''
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- mount for output later
|
||||
|
||||
+7
-7
@@ -25,15 +25,15 @@ This is the status of all module tests.
|
||||
See the **Todo** section for outstanding tasks if you want to contribute!
|
||||
| Module | Done | Skip | Modules | Done | Skip |
|
||||
| ----------------- | ---- | ---- | ---------------- | ---- | ---- |
|
||||
| 🟢 audio | 28 | 0 | 🟢 mouse | 18 | 0 |
|
||||
| 🟢 audio | 31 | 0 | 🟢 mouse | 18 | 0 |
|
||||
| 🟢 data | 12 | 0 | 🟢 physics | 26 | 0 |
|
||||
| 🟢 event | 4 | 2 | 🟢 sensor | 1 | 0 |
|
||||
| 🟢 filesystem | 29 | 2 | 🟢 sound | 4 | 0 |
|
||||
| 🟢 font | 7 | 0 | 🟢 system | 6 | 2 |
|
||||
| 🟢 graphics | 104 | 1 | 🟢 thread | 5 | 0 |
|
||||
| 🟢 filesystem | 33 | 2 | 🟢 sound | 4 | 0 |
|
||||
| 🟢 font | 7 | 0 | 🟢 system | 7 | 2 |
|
||||
| 🟢 graphics | 105 | 1 | 🟢 thread | 5 | 0 |
|
||||
| 🟢 image | 5 | 0 | 🟢 timer | 6 | 0 |
|
||||
| 🟢 joystick | 6 | 0 | 🟢 touch | 3 | 0 |
|
||||
| 🟢 keyboard | 9 | 0 | 🟢 video | 2 | 0 |
|
||||
| 🟢 keyboard | 10 | 0 | 🟢 video | 2 | 0 |
|
||||
| 🟢 love | 6 | 0 | 🟢 window | 34 | 2 |
|
||||
| 🟢 math | 20 | 0 |
|
||||
|
||||
@@ -102,7 +102,7 @@ love.test.filesystem.read = function(test)
|
||||
end
|
||||
```
|
||||
|
||||
Each test is run inside it's own coroutine - you can use `test:waitFrames(frames)` to pause the test for a small period if you need to check things that won't happen for a few seconds.
|
||||
Each test is run inside it's own coroutine - you can use `test:waitFrames(frames)` or `test:waitSeconds(seconds)` to pause the test for a small period if you need to check things that won't happen for a few frames/seconds.
|
||||
|
||||
After each test method is ran, the assertions are totalled up, printed, and we move onto the next method! Once all methods in the suite are run a total pass/fail/skip is given for that module and we move onto the next module (if any)
|
||||
|
||||
@@ -133,7 +133,7 @@ The automated tests through Github work for the most part however there are a fe
|
||||
|
||||
These exceptions are either skipped, or handled by using a 1px or 1/255rgba tolerance - when run locally on real hardware, these tests pass fine at the default 0 tolerance.
|
||||
You can specify the test suite is being run on a runner by adding the `--isRunner` flag in your workflow file, i.e.:
|
||||
`& 'c:\Program Files\LOVE\love.exe' PATH_TO_TESTING_FOLDER/main.lua --console --runAllTests --isRunner`
|
||||
`& 'c:\Program Files\LOVE\love.exe' PATH_TO_TESTING_FOLDER/main.lua --console --all --isRunner`
|
||||
| Test | OS | Exception | Reason |
|
||||
| -------------------------- | --------- | ------------------- | ------ |
|
||||
| love.graphics.setWireframe | MacOS | 1px tolerance | Wireframes are offset by 1,1 when drawn |
|
||||
|
||||
@@ -469,7 +469,7 @@ love.test.audio.setPlaybackDevice = function(test)
|
||||
-- rn on macos all 3 return false
|
||||
-- whereas linux/windows return true for blank/current, which is expected
|
||||
-- as openalsoft treats blank as current
|
||||
if love.system.getOS() == 'OS X' then
|
||||
if test:isOS('OS X') then
|
||||
test:assertFalse(success1, 'check blank device fails')
|
||||
test:assertFalse(success2, 'check invalid device fails')
|
||||
test:assertFalse(success3, 'check existing device fails')
|
||||
|
||||
@@ -393,7 +393,7 @@ love.test.filesystem.mountCommonPath = function(test)
|
||||
local mount3 = love.filesystem.mountCommonPath('userhome', 'userhome', 'readwrite')
|
||||
local mount4 = love.filesystem.mountCommonPath('userappdata', 'userappdata', 'readwrite')
|
||||
-- userdesktop isnt valid on linux
|
||||
if love.system.getOS() ~= 'Linux' then
|
||||
if not test:isOS('Linux') then
|
||||
local mount5 = love.filesystem.mountCommonPath('userdesktop', 'userdesktop', 'readwrite')
|
||||
test:assertTrue(mount5, 'check mount userdesktop')
|
||||
end
|
||||
|
||||
+26
-19
@@ -10,56 +10,53 @@
|
||||
|
||||
-- GraphicsBuffer (love.graphics.newBuffer)
|
||||
love.test.graphics.Buffer = function(test)
|
||||
|
||||
-- setup vertex data and create some buffers
|
||||
local vertexformat = {
|
||||
{name="VertexPosition", format="floatvec2"},
|
||||
{name="VertexTexCoord", format="floatvec2"},
|
||||
{name="VertexColor", format="unorm8vec4"},
|
||||
}
|
||||
|
||||
local vertexdata = {
|
||||
{0, 0, 0, 0, 1, 0, 1, 1},
|
||||
{10, 0, 1, 0, 0, 1, 1, 1},
|
||||
{10, 10, 1, 1, 0, 0, 1, 1},
|
||||
{0, 10, 0, 1, 1, 0, 0, 1},
|
||||
}
|
||||
|
||||
local flatvertexdata = {}
|
||||
for i, vert in ipairs(vertexdata) do
|
||||
for j, v in ipairs(vert) do
|
||||
table.insert(flatvertexdata, v)
|
||||
end
|
||||
end
|
||||
|
||||
local vertexbuffer1 = love.graphics.newBuffer(vertexformat, 4, {vertex=true, debugname='testvertexbuffer'})
|
||||
local vertexbuffer2 = love.graphics.newBuffer(vertexformat, vertexdata, {vertex=true})
|
||||
|
||||
test:assertObject(vertexbuffer1)
|
||||
test:assertObject(vertexbuffer2)
|
||||
|
||||
-- check buffer properties
|
||||
test:assertEquals(4, vertexbuffer1:getElementCount(), 'check vertex count 1')
|
||||
test:assertEquals(4, vertexbuffer2:getElementCount(), 'check vertex count 2')
|
||||
|
||||
-- vertex buffers have their elements tightly packed.
|
||||
test:assertEquals(20, vertexbuffer1:getElementStride(), 'check vertex array stride')
|
||||
|
||||
test:assertEquals(20 * 4, vertexbuffer1:getSize(), 'check vertex buffer size')
|
||||
|
||||
vertexbuffer1:setArrayData(vertexdata)
|
||||
vertexbuffer1:setArrayData(flatvertexdata)
|
||||
|
||||
vertexbuffer1:clear(8, 8) -- partial clear (the first texcoord)
|
||||
|
||||
-- check buffer types
|
||||
test:assertTrue(vertexbuffer1:isBufferType('vertex'), 'check is vertex buffer')
|
||||
test:assertFalse(vertexbuffer1:isBufferType('index'), 'check is not index buffer')
|
||||
test:assertFalse(vertexbuffer1:isBufferType('texel'), 'check is not texel buffer')
|
||||
test:assertFalse(vertexbuffer1:isBufferType('shaderstorage'), 'check is not shader storage buffer')
|
||||
|
||||
-- check debug name
|
||||
test:assertEquals('testvertexbuffer', vertexbuffer1:getDebugName(), 'check buffer debug name')
|
||||
|
||||
-- check buffer format and format properties
|
||||
local format = vertexbuffer1:getFormat()
|
||||
test:assertEquals('table', type(format), 'check buffer format is table')
|
||||
test:assertEquals(#vertexformat, #format, 'check buffer format length')
|
||||
|
||||
for i, v in ipairs(vertexformat) do
|
||||
test:assertEquals(v.name, format[i].name, string.format('check buffer format %d name', i))
|
||||
test:assertEquals(v.format, format[i].format, string.format('check buffer format %d format', i))
|
||||
@@ -67,8 +64,10 @@ love.test.graphics.Buffer = function(test)
|
||||
test:assertNotNil(format[i].offset)
|
||||
end
|
||||
|
||||
-- check index buffer
|
||||
local indexbuffer = love.graphics.newBuffer('uint16', 128, {index=true})
|
||||
test:assertTrue(indexbuffer:isBufferType('index'), 'check is index buffer')
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -80,22 +79,22 @@ love.test.graphics.ShaderStorageBuffer = function(test)
|
||||
return
|
||||
end
|
||||
|
||||
-- setup buffer
|
||||
local format = {
|
||||
{ name="1", format="float" },
|
||||
{ name="2", format="floatmat4x4" },
|
||||
{ name="3", format="floatvec2" }
|
||||
}
|
||||
|
||||
local buffer = love.graphics.newBuffer(format, 1, {shaderstorage = true})
|
||||
|
||||
test:assertEquals(96, buffer:getElementStride(), 'check shader storage buffer element stride')
|
||||
|
||||
-- set new data
|
||||
local data = {}
|
||||
for i = 1, 19 do
|
||||
data[i] = 0
|
||||
end
|
||||
|
||||
buffer:setArrayData(data)
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1170,7 +1169,7 @@ love.test.graphics.arc = function(test)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.setCanvas()
|
||||
local imgdata3 = love.graphics.readbackTexture(canvas)
|
||||
if GITHUB_RUNNER and love.system.getOS() == 'OS X' then
|
||||
if GITHUB_RUNNER and test:isOS('OS X') then
|
||||
-- on macosx runners, the arcs are not drawn as accurately at low res
|
||||
-- there's a couple pixels different in the curve of the arc but as we
|
||||
-- are at such a low resolution I think that can be expected
|
||||
@@ -1468,7 +1467,7 @@ love.test.graphics.captureScreenshot = function(test)
|
||||
TextCommand = prevtextcommand
|
||||
test:assertNotNil(cbdata)
|
||||
|
||||
if love.system.getOS() == "iOS" or love.system.getOS() == "Android" then
|
||||
if test:isOS({'iOS', 'Android'}) then
|
||||
-- Mobile operating systems don't let us control the window resolution,
|
||||
-- so we can't compare the reference image properly.
|
||||
test:assertTrue(true, 'skip test')
|
||||
@@ -1586,7 +1585,7 @@ love.test.graphics.newSpriteBatch = function(test)
|
||||
end
|
||||
|
||||
|
||||
-- love.graphics.newText
|
||||
-- love.graphics.newTextBatch
|
||||
-- @NOTE this is just basic nil checking, objs have their own test method
|
||||
love.test.graphics.newTextBatch = function(test)
|
||||
local font = love.graphics.newFont('resources/font.ttf')
|
||||
@@ -1594,6 +1593,14 @@ love.test.graphics.newTextBatch = function(test)
|
||||
end
|
||||
|
||||
|
||||
-- love.graphics.newTexture
|
||||
-- @NOTE this is just basic nil checking, objs have their own test method
|
||||
love.test.graphics.newTexture = function(test)
|
||||
local imgdata = love.image.newImageData('resources/love.png')
|
||||
test:assertObject(love.graphics.newTexture(imgdata))
|
||||
end
|
||||
|
||||
|
||||
-- love.graphics.newVideo
|
||||
-- @NOTE this is just basic nil checking, objs have their own test method
|
||||
love.test.graphics.newVideo = function(test)
|
||||
@@ -2167,7 +2174,7 @@ love.test.graphics.setLineStyle = function(test)
|
||||
love.graphics.setCanvas()
|
||||
local imgdata = love.graphics.readbackTexture(canvas)
|
||||
-- linux runner needs a 1/255 tolerance for the blend between a rough line + bg
|
||||
if GITHUB_RUNNER and love.system.getOS() == 'Linux' then
|
||||
if GITHUB_RUNNER and test:isOS('Linux') then
|
||||
test.rgba_tolerance = 1
|
||||
end
|
||||
test:compareImg(imgdata)
|
||||
@@ -2300,7 +2307,7 @@ love.test.graphics.setWireframe = function(test)
|
||||
love.graphics.setWireframe(false)
|
||||
local imgdata = love.graphics.readbackTexture(canvas)
|
||||
-- on macOS runners wireframes are drawn 1px off from the target
|
||||
if GITHUB_RUNNER and love.system.getOS() == 'OS X' then
|
||||
if GITHUB_RUNNER and test:isOS('OS X') then
|
||||
test.pixel_tolerance = 1
|
||||
end
|
||||
test:compareImg(imgdata)
|
||||
@@ -2667,8 +2674,8 @@ love.test.graphics.getSupported = function(test)
|
||||
'clampzero', 'lighten', 'glsl3', 'instancing', 'fullnpot',
|
||||
'pixelshaderhighp', 'shaderderivatives', 'indirectdraw', 'mipmaprange',
|
||||
'copyrendertargettobuffer', 'copytexturetobuffer', 'copybuffer',
|
||||
'indexbuffer32bit', 'multirendertargetformats', 'clampone', 'blendminmax',
|
||||
'glsl4'
|
||||
'copybuffertotexture', 'indexbuffer32bit', 'multirendertargetformats',
|
||||
'clampone', 'blendminmax', 'glsl4'
|
||||
}
|
||||
local features = love.graphics.getSupported()
|
||||
for g=1,#gfs do
|
||||
|
||||
@@ -3,7 +3,6 @@ These are all the outstanding methods that require test coverage, along with a f
|
||||
|
||||
## General
|
||||
- ability to test loading different combinations of modules if needed?
|
||||
- performance tests? need to discuss what + how, might be better as a seperate thing
|
||||
- check expected behaviour of mount + unmount with common path
|
||||
try uncommenting love.filesystem.unmountCommonPath and you'll see the issues
|
||||
- revisit love.audio.setPlaybackDevice when we update openal soft for MacOS
|
||||
@@ -19,7 +18,6 @@ These are all the outstanding methods that require test coverage, along with a f
|
||||
- love.graphics.newComputeShader()
|
||||
- love.graphics.dispatchThreadgroups()
|
||||
- love.graphics.dispatchIndirect()
|
||||
- love.graphics.newTexture()
|
||||
- love.graphics.drawFromShader()
|
||||
- love.graphics.drawFromShaderIndirect()
|
||||
- love.graphics.drawIndirect()
|
||||
|
||||
Reference in New Issue
Block a user