diff --git a/testing/classes/TestMethod.lua b/testing/classes/TestMethod.lua index f4f8688d6..2061a8187 100644 --- a/testing/classes/TestMethod.lua +++ b/testing/classes/TestMethod.lua @@ -367,11 +367,19 @@ TestMethod = { end, + -- @method - TestMethod:waitFrames() + -- @desc - yields the method for x amount of frames + -- @param {number} frames - no. frames to wait + -- @return {nil} waitFrames = function(self, frames) - for i=1,frames do coroutine.yield() end + for _=1,frames do coroutine.yield() end end, + -- @method - TestMethod:waitSeconds() + -- @desc - yields the method for x amount of seconds + -- @param {number} seconds - no. seconds to wait + -- @return {nil} waitSeconds = function(self, seconds) local start = love.timer.getTime() while love.timer.getTime() < start + seconds do diff --git a/testing/conf.lua b/testing/conf.lua index 787650a49..79e5f16d8 100644 --- a/testing/conf.lua +++ b/testing/conf.lua @@ -1,4 +1,7 @@ +print("conf.lua") + function love.conf(t) + print("love.conf") t.console = true t.window.name = 'love.test' t.window.width = 360 @@ -8,3 +11,14 @@ function love.conf(t) t.window.stencil = true t.renderers = {"opengl"} end + +-- custom crash message here to catch anything that might occur with modules +-- loading before we hit main.lua +local function error_printer(msg, layer) + print((debug.traceback("Error: " .. tostring(msg), 1+(layer or 1)):gsub("\n[^\n]+$", ""))) +end +function love.errorhandler(msg) + msg = tostring(msg) + error_printer(msg, 2) + os.exit(1) +end diff --git a/testing/main.lua b/testing/main.lua index 6c7b26165..ca2d71608 100644 --- a/testing/main.lua +++ b/testing/main.lua @@ -1,3 +1,5 @@ +print('main.lua') + -- load test objs require('classes.TestSuite') require('classes.TestModule') diff --git a/testing/readme.md b/testing/readme.md index dab1cd7cb..9b328023d 100644 --- a/testing/readme.md +++ b/testing/readme.md @@ -114,14 +114,7 @@ For sanity-checking, if it's currently not covered or it's not possible to test ## Todo If you would like to contribute to the test suite please raise a PR with the main [love-test](https://github.com/ellraiser/love-test) repo. -The following items are all the things still outstanding, expanding on any existing tests is also very welcome! -- [ ] check for any 12.0 methods in the changelog not yet covered in the test suite -- [ ] add BMfont alt. tests for font class tests (Rasterizer + GlyphData) -- [ ] graphics.isCompressed() should have an example of all compressed files -- [ ] graphics.Mesh should have some graphical tests ideally to check vertex settings w/ shaders -- [ ] ability to test loading different combinations of modules if needed -- [ ] more scenario based tests similar to some of the obj class tests -- [ ] performance tests? need to discuss what + how +There is a list of outstanding methods that require test coverage in `todo.md`, expanding on any existing tests is also very welcome! --- diff --git a/testing/resources/pop.ogg b/testing/resources/pop.ogg new file mode 100644 index 000000000..fb0a82a7b Binary files /dev/null and b/testing/resources/pop.ogg differ diff --git a/testing/resources/tone.ogg b/testing/resources/tone.ogg new file mode 100644 index 000000000..1e7156e47 Binary files /dev/null and b/testing/resources/tone.ogg differ diff --git a/testing/tests/audio.lua b/testing/tests/audio.lua index 39133ab91..24eb7ea0a 100644 --- a/testing/tests/audio.lua +++ b/testing/tests/audio.lua @@ -299,6 +299,20 @@ love.test.audio.getOrientation = function(test) end +-- love.audio.getPlaybackDevice +love.test.audio.getPlaybackDevice = function(test) + test:assertNotNil(love.audio.getPlaybackDevice) + test:assertNotNil(love.audio.getPlaybackDevice()) +end + + +-- love.audio.getPlaybackDevices +love.test.audio.getPlaybackDevices = function(test) + test:assertNotNil(love.audio.getPlaybackDevices) + test:assertGreaterEqual(0, #love.audio.getPlaybackDevices(), 'check table') +end + + -- love.audio.getPosition -- @NOTE is there an expected default listener pos? love.test.audio.getPosition = function(test) @@ -442,6 +456,52 @@ love.test.audio.setOrientation = function(test) end +-- love.audio.setPlaybackDevice +love.test.audio.setPlaybackDevice = function(test) + -- check method + test:assertNotNil(love.audio.setPlaybackDevice) + -- check blank string name + local success1, msg1 = love.audio.setPlaybackDevice('') + -- check invalid name + local success2, msg2 = love.audio.setPlaybackDevice('loveFM') + -- check setting already set + local success3, msg3 = love.audio.setPlaybackDevice(love.audio.getPlaybackDevice()) -- current name + -- 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 + test:assertFalse(success1, 'check blank device fails') + test:assertFalse(success2, 'check invalid device fails') + test:assertFalse(success3, 'check existing device fails') + else + test:assertTrue(success1, 'check blank device is fine') + test:assertFalse(success2, 'check invalid device fails') + test:assertTrue(success3, 'check existing device is fine') + end + -- if other devices to play with lets set a different one + local devices = love.audio.getPlaybackDevices() + if #devices > 1 then + local another = '' + local current = love.audio.getPlaybackDevice() + for a=1,#devices do + if devices[a] ~= current then + another = devices[a] + break + end + end + if another ~= '' then + -- check setting new device + local success4, msg4 = love.audio.setPlaybackDevice(another) + test:assertTrue(success4, 'check setting different device') + -- check resetting to default + local success5, msg5 = love.audio.setPlaybackDevice() + test:assertTrue(success5, 'check resetting') + test:assertEquals(current, love.audio.getPlaybackDevice()) + end + end +end + + -- love.audio.setPosition love.test.audio.setPosition = function(test) -- check setting position vals are returned diff --git a/testing/tests/data.lua b/testing/tests/data.lua index 21b66b609..725d25f99 100644 --- a/testing/tests/data.lua +++ b/testing/tests/data.lua @@ -33,6 +33,10 @@ love.test.data.ByteData = function(test) test:assertEquals('o', byte5) end + -- check overwriting the byte data string + data:setString('love!', 5) + test:assertEquals('hellolove!', data:getString(), 'check change string') + end diff --git a/testing/tests/filesystem.lua b/testing/tests/filesystem.lua index 55e112553..c7d76e6f6 100644 --- a/testing/tests/filesystem.lua +++ b/testing/tests/filesystem.lua @@ -187,6 +187,27 @@ love.test.filesystem.getDirectoryItems = function(test) end +-- love.filesystem.getFullCommonPath +love.test.filesystem.getFullCommonPath = function(test) + -- check standard paths + local appsavedir = love.filesystem.getFullCommonPath('appsavedir') + local appdocuments = love.filesystem.getFullCommonPath('appdocuments') + local userhome = love.filesystem.getFullCommonPath('userhome') + local userappdata = love.filesystem.getFullCommonPath('userappdata') + local userdesktop = love.filesystem.getFullCommonPath('userdesktop') + local userdocuments = love.filesystem.getFullCommonPath('userdocuments') + test:assertNotNil(appsavedir) + test:assertNotNil(appdocuments) + test:assertNotNil(userhome) + test:assertNotNil(userappdata) + test:assertNotNil(userdesktop) + test:assertNotNil(userdocuments) + -- check invalid path + local ok = pcall(love.filesystem.getFullCommonPath, 'fakepath') + test:assertFalse(ok, 'check invalid common path') +end + + -- love.filesystem.getIdentity love.test.filesystem.getIdentity = function(test) -- check setting identity matches @@ -263,6 +284,7 @@ love.test.filesystem.getInfo = function(test) test:assertEquals(nil, love.filesystem.getInfo('foo/bar/file2.txt', 'directory'), 'check not directory') test:assertNotEquals(nil, love.filesystem.getInfo('foo/bar/file2.txt'), 'check info not nil') test:assertEquals(love.filesystem.getInfo('foo/bar/file2.txt').size, 5, 'check info size match') + test:assertFalse(love.filesystem.getInfo('foo/bar/file2.txt').readonly, 'check readonly') -- @TODO test modified timestamp from info.modtime? -- cleanup love.filesystem.remove('foo/bar/file2.txt') @@ -300,12 +322,16 @@ love.test.filesystem.load = function(test) love.filesystem.write('test1.lua', 'function test()\nreturn 1\nend\nreturn test()') love.filesystem.write('test2.lua', 'function test()\nreturn 1') -- check file that doesn't exist - local chunk, errormsg = love.filesystem.load('faker.lua') - test:assertEquals(nil, chunk, 'check file doesnt exist') - -- check valid lua file - chunk, errormsg = love.filesystem.load('test1.lua') - test:assertEquals(nil, errormsg, 'check no error message') - test:assertEquals(1, chunk(), 'check lua file runs') + local chunk1, errormsg1 = love.filesystem.load('faker.lua', 'b') + test:assertEquals(nil, chunk1, 'check file doesnt exist') + -- check valid lua file (text load) + local chunk2, errormsg2 = love.filesystem.load('test1.lua', 't') + test:assertEquals(nil, errormsg2, 'check no error message') + test:assertEquals(1, chunk2(), 'check lua file runs') + -- check valid lua file (any load) + local chunk4, errormsg4 = love.filesystem.load('test1.lua', 'bt') + test:assertEquals(nil, errormsg2, 'check no error message') + test:assertEquals(1, chunk4(), 'check lua file runs') -- check invalid lua file local ok, chunk, err = pcall(love.filesystem.load, 'test2.lua') test:assertFalse(ok, 'check invalid lua file') @@ -334,6 +360,88 @@ love.test.filesystem.mount = function(test) end +-- love.filesystem.mountFullPath +love.test.filesystem.mountFullPath = function(test) + -- mount something in the working directory + local mount = love.filesystem.mountFullPath(love.filesystem.getSource() .. '/tests', 'tests', 'read') + test:assertTrue(mount, 'check can mount') + -- check reading file through mounted path label + local contents, _ = love.filesystem.read('tests/audio.lua') + test:assertNotEquals(nil, contents) + local unmount = love.filesystem.unmountFullPath(love.filesystem.getSource() .. '/tests') + test:assertTrue(unmount, 'reset mount') +end + + +-- love.filesystem.unmountFullPath +love.test.filesystem.unmountFullPath = function(test) + -- try unmounting something we never mounted + local unmount1 = love.filesystem.unmountFullPath(love.filesystem.getSource() .. '/faker') + test:assertFalse(unmount1, 'check not mounted to start with') + -- mount something to unmount after + love.filesystem.mountFullPath(love.filesystem.getSource() .. '/tests', 'tests', 'read') + local unmount2 = love.filesystem.unmountFullPath(love.filesystem.getSource() .. '/tests') + test:assertTrue(unmount2, 'check unmounted') +end + + +-- love.filesystem.mountCommonPath +love.test.filesystem.mountCommonPath = function(test) + -- check if we can mount all the expected paths + local mount1 = love.filesystem.mountCommonPath('appsavedir', 'appsavedir', 'readwrite') + local mount2 = love.filesystem.mountCommonPath('appdocuments', 'appdocuments', 'readwrite') + 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 + local mount5 = love.filesystem.mountCommonPath('userdesktop', 'userdesktop', 'readwrite') + test:assertTrue(mount5, 'check mount userdesktop') + end + local mount6 = love.filesystem.mountCommonPath('userdocuments', 'userdocuments', 'readwrite') + local ok = pcall(love.filesystem.mountCommonPath, 'fakepath', 'fake', 'readwrite') + test:assertTrue(mount1, 'check mount appsavedir') + test:assertTrue(mount2, 'check mount appdocuments') + test:assertTrue(mount3, 'check mount userhome') + test:assertTrue(mount4, 'check mount userappdata') + test:assertTrue(mount6, 'check mount userdocuments') + test:assertFalse(ok, 'check mount invalid common path fails') +end + + +-- love.filesystem.unmountCommonPath +--love.test.filesystem.unmountCommonPath = function(test) +-- -- check unmounting invalid +-- local ok = pcall(love.filesystem.unmountCommonPath, 'fakepath') +-- test:assertFalse(ok, 'check unmount invalid common path') +-- -- check mounting valid paths +-- love.filesystem.mountCommonPath('appsavedir', 'appsavedir', 'read') +-- love.filesystem.mountCommonPath('appdocuments', 'appdocuments', 'read') +-- love.filesystem.mountCommonPath('userhome', 'userhome', 'read') +-- love.filesystem.mountCommonPath('userappdata', 'userappdata', 'read') +-- love.filesystem.mountCommonPath('userdesktop', 'userdesktop', 'read') +-- love.filesystem.mountCommonPath('userdocuments', 'userdocuments', 'read') +-- local unmount1 = love.filesystem.unmountCommonPath('appsavedir') +-- local unmount2 = love.filesystem.unmountCommonPath('appdocuments') +-- local unmount3 = love.filesystem.unmountCommonPath('userhome') +-- local unmount4 = love.filesystem.unmountCommonPath('userappdata') +-- local unmount5 = love.filesystem.unmountCommonPath('userdesktop') +-- local unmount6 = love.filesystem.unmountCommonPath('userdocuments') +-- test:assertTrue(unmount1, 'check unmount appsavedir') +-- test:assertTrue(unmount2, 'check unmount appdocuments') +-- test:assertTrue(unmount3, 'check unmount userhome') +-- test:assertTrue(unmount4, 'check unmount userappdata') +-- test:assertTrue(unmount5, 'check unmount userdesktop') +-- test:assertTrue(unmount6, 'check unmount userdocuments') +-- -- remount or future tests fail +-- love.filesystem.mountCommonPath('appsavedir', 'appsavedir', 'readwrite') +-- love.filesystem.mountCommonPath('appdocuments', 'appdocuments', 'readwrite') +-- love.filesystem.mountCommonPath('userhome', 'userhome', 'readwrite') +-- love.filesystem.mountCommonPath('userappdata', 'userappdata', 'readwrite') +-- love.filesystem.mountCommonPath('userdesktop', 'userdesktop', 'readwrite') +-- love.filesystem.mountCommonPath('userdocuments', 'userdocuments', 'readwrite') +--end + + -- love.filesystem.openFile -- @NOTE this is just basic nil checking, objs have their own test method love.test.filesystem.openFile = function(test) diff --git a/testing/tests/graphics.lua b/testing/tests/graphics.lua index da473da87..ae4079382 100644 --- a/testing/tests/graphics.lua +++ b/testing/tests/graphics.lua @@ -113,6 +113,8 @@ love.test.graphics.Canvas = function(test) debugname = 'testcanvas' }) test:assertObject(canvas) + test:assertTrue(canvas:isCanvas(), 'check is canvas') + test:assertFalse(canvas:isComputeWritable(), 'check not compute writable') -- check dpi test:assertEquals(love.graphics.getDPIScale(), canvas:getDPIScale(), 'check dpi scale') @@ -216,6 +218,16 @@ love.test.graphics.Canvas = function(test) dcanvas:setDepthSampleMode('equal') test:assertEquals('equal', dcanvas:getDepthSampleMode(), 'check depth sample mode set') + -- check compute writeable (wont work on opengl mac) + if love.graphics.getSupported().glsl4 then + local ccanvas = love.graphics.newCanvas(100, 100, { + type = '2d', + format = 'rgba8', + computewrite = true + }) + test:assertTrue(ccanvas:isComputeWritable()) + end + end @@ -303,6 +315,8 @@ love.test.graphics.Image = function(test) mipmaps = true }) test:assertObject(image) + test:assertFalse(image:isCanvas(), 'check not canvas') + test:assertFalse(image:isComputeWritable(), 'check not compute writable') -- check dpi test:assertEquals(love.graphics.getDPIScale(), image:getDPIScale(), 'check dpi scale') diff --git a/testing/tests/image.lua b/testing/tests/image.lua index fa9f4cbd2..7cdcc878b 100644 --- a/testing/tests/image.lua +++ b/testing/tests/image.lua @@ -32,6 +32,11 @@ love.test.image.CompressedImageData = function(test) -- check mipmap count test:assertEquals(7, idata:getMipmapCount(), 'check mipmap count') + -- check linear + test:assertFalse(idata:isLinear(), 'check not linear') + idata:setLinear(true) + test:assertTrue(idata:isLinear(), 'check now linear') + end @@ -78,12 +83,23 @@ love.test.image.ImageData = function(test) local r2, g2, b2 = idata:getPixel(25, 25) test:assertEquals(1, r2+g2+b2, 'check set to red') - -- check encoding to an image + -- check encoding to an image (png) idata:encode('png', 'test-encode.png') - local read = love.filesystem.openFile('test-encode.png', 'r') - test:assertNotNil(read) + local read1 = love.filesystem.openFile('test-encode.png', 'r') + test:assertNotNil(read1) love.filesystem.remove('test-encode.png') + -- check encoding to an image (exr) + idata:encode('png', 'test-encode.exr') + local read2 = love.filesystem.openFile('test-encode.exr', 'r') + test:assertNotNil(read2) + love.filesystem.remove('test-encode.exr') + + -- check linear + test:assertFalse(idata:isLinear(), 'check not linear') + idata:setLinear(true) + test:assertTrue(idata:isLinear(), 'check now linear') + end diff --git a/testing/tests/keyboard.lua b/testing/tests/keyboard.lua index e7a4f5630..c8f9748c9 100644 --- a/testing/tests/keyboard.lua +++ b/testing/tests/keyboard.lua @@ -64,6 +64,19 @@ love.test.keyboard.setKeyRepeat = function(test) end +-- love.keyboard.isModifierActive +love.test.keyboard.isModifierActive = function(test) + local active1 = love.keyboard.isModifierActive('numlock') + local active2 = love.keyboard.isModifierActive('capslock') + local active3 = love.keyboard.isModifierActive('scrolllock') + local active4 = love.keyboard.isModifierActive('mode') + test:assertNotNil(active1) + test:assertNotNil(active2) + test:assertNotNil(active3) + test:assertNotNil(active4) +end + + -- love.keyboard.setTextInput love.test.keyboard.setTextInput = function(test) love.keyboard.setTextInput(false) diff --git a/testing/tests/sound.lua b/testing/tests/sound.lua index 0304d0562..d5032cb30 100644 --- a/testing/tests/sound.lua +++ b/testing/tests/sound.lua @@ -80,6 +80,18 @@ love.test.sound.SoundData = function(test) sdata:setSample(0.002, 1) test:assertEquals(1, sdata:getSample(0.002), 'check setting sample manually') + -- check copying from another sound + local copy1 = love.sound.newSoundData('resources/tone.ogg') + local copy2 = love.sound.newSoundData('resources/pop.ogg') + local before = copy2:getSample(0.02) + copy2:copyFrom(copy1, 0.01, 1, 0.02) + test:assertNotEquals(before, copy2:getSample(0.02), 'check changed') + + -- check slicing + local count = math.floor(copy1:getSampleCount()/2) + local slice = copy1:slice(0, count) + test:assertEquals(count, slice:getSampleCount(), 'check slice length') + end diff --git a/testing/tests/system.lua b/testing/tests/system.lua index e8ef4229c..88912d525 100644 --- a/testing/tests/system.lua +++ b/testing/tests/system.lua @@ -29,6 +29,14 @@ love.test.system.getOS = function(test) end +-- love.system.getPreferredLocales +love.test.system.getPreferredLocales = function(test) + local locale = love.system.getPreferredLocales() + test:assertNotNil(locale) + test:assertEquals('table', type(locale), 'check returns table') +end + + -- love.system.getPowerInfo love.test.system.getPowerInfo = function(test) -- check battery state is one of the documented states diff --git a/testing/tests/window.lua b/testing/tests/window.lua index b1c993776..98cfc2f43 100644 --- a/testing/tests/window.lua +++ b/testing/tests/window.lua @@ -8,6 +8,13 @@ -------------------------------------------------------------------------------- +-- love.window.focus +love.test.window.focus = function(test) + -- cant test as doesnt return anything + test:assertEquals('function', type(love.window.focus), 'check method exists') +end + + -- love.window.fromPixels love.test.window.fromPixels = function(test) -- check dpi/pixel ratio as expected @@ -352,18 +359,3 @@ love.test.window.updateMode = function(test) resizable = true }) end - --- love.window.close --- calling love.window.close() last as it will stop the main test image drawing -love.test.window.z_close = function(test) - -- closing window should cause graphics to not be active - love.window.close() - local active = love.graphics.isActive() - test:assertFalse(active, 'check window not active') - -- should also mark the window as not open and not visible - test:assertFalse(love.window.isOpen(), 'check window closed') - test:assertFalse(love.window.isVisible(), 'check window not visible') - love.window.updateMode(360, 240) -- reset - active = love.graphics.isActive() - test:assertTrue(active, 'check window active again') -end diff --git a/testing/todo.md b/testing/todo.md new file mode 100644 index 000000000..026148b81 --- /dev/null +++ b/testing/todo.md @@ -0,0 +1,40 @@ +# TODO +These are all the outstanding methods that require test coverage, along with a few bits that still need doing / discussion. + +## 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 + +## Physics +- love.physics.World:rayCastAny +- love.physics.World:rayCastClosest +- love.physics.World:getShapesInArea +- love.physics.Body:getShapes +- love.physics.Body:getShape +- love.physics.Body:hasCustomMassData + +## Graphics +- love.graphics.copyBuffer +- love.graphics.copyBufferToTexture +- love.graphics.copyTextureToBuffer +- love.graphics.readbackTexture +- love.graphics.readbackTextureAsync +- love.graphics.readbackBuffer +- love.graphics.readbackBufferAsync +- love.graphics.newComputeShader +- love.graphics.dispatchThreadgroupos +- love.graphics.dispatchIndirect +- love.graphics.newTexture +- love.graphics.drawFromShader +- love.graphics.drawFromShaderIndirect +- love.graphics.drawIndirect +- love.graphics.getQuadIndexBuffer +- love.graphics.setBlendState +- love.graphics.setOrthoProjection +- love.graphics.setPerspectiveProjection +- love.graphics.resetProjection +- Mesh:getAttachedAttributes +- Shader:hasStage