From 825e46621ea6e75c681898885edf9f80412f105f Mon Sep 17 00:00:00 2001 From: ell <77150506+ellraiser@users.noreply.github.com> Date: Mon, 20 Nov 2023 20:05:30 +0000 Subject: [PATCH] finished obj tests - added physics.Contact, physics.Body, and physics.Shape obj tests - added graphics.Mesh and graphics.ParticleSystem obj tests - fixed some rgba tolerance needed on a couple methods - added test conclusion to zip artifact name for quick checking on PRs - ignored testsuite on compat mode windows builds --- .github/workflows/main.yml | 38 ++- testing/main.lua | 9 +- .../love.test.graphics.ParticleSystem-1.png | Bin 0 -> 134 bytes testing/readme.md | 65 ++-- testing/resources/pixel.png | Bin 0 -> 81 bytes testing/tests/graphics.lua | 286 +++++++++++++++- testing/tests/physics.lua | 322 +++++++++++++++++- 7 files changed, 668 insertions(+), 52 deletions(-) create mode 100644 testing/output/expected/love.test.graphics.ParticleSystem-1.png create mode 100644 testing/resources/pixel.png diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ff76eb63e..d9a4154a8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,6 +63,7 @@ jobs: chmod a+x love-${{ github.sha }}.AppImage ./love-${{ github.sha }}.AppImage love2d-${{ github.sha }}/testing/main.lua --runAllTests --isRunner - name: Love Test Report (opengl) + id: report1 uses: ellraiser/love-test-report@main with: name: Love Testsuite Linux @@ -75,7 +76,7 @@ jobs: - name: Artifact Test Output (opengl) uses: actions/upload-artifact@v3 with: - name: test-output-linux-opengl + name: test-output-linux-opengl-${{ steps.report1.outputs.conclusion }} path: test-output-linux-opengl.zip # linux opengles tests - name: Run Test Suite (opengles) @@ -84,6 +85,7 @@ jobs: ./love-${{ github.sha }}.AppImage love2d-${{ github.sha }}/testing/main.lua --runAllTests --isRunner - name: Love Test Report (opengles) uses: ellraiser/love-test-report@main + id: report2 with: name: Love Testsuite Linux title: test-report-linux-opengles @@ -95,7 +97,7 @@ jobs: - name: Artifact Test Output (opengles) uses: actions/upload-artifact@v3 with: - name: test-output-linux-opengles + name: test-output-linux-opengles-${{ steps.report2.outputs.conclusion }} path: test-output-linux-opengles.zip # # linux vulkan tests # - name: Run Test Suite (vulkan) @@ -297,23 +299,25 @@ jobs: path: pdb/Release/*.pdb # install mesa for graphic tests - name: Install Mesa + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: | curl -L --output mesa.7z --url https://github.com/pal1000/mesa-dist-win/releases/download/23.2.1/mesa3d-23.2.1-release-msvc.7z 7z x mesa.7z -o* powershell.exe mesa\systemwidedeploy.cmd 1 # build love to use for the tests - name: Build Test Exe - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: cmake --build build --config Release --target install # windows opengl tests - name: Run Tests (opengl) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: | echo 'check dir' ls powershell.exe ./install/lovec.exe ./megasource/libs/love/testing/main.lua --runAllTests --isRunner - name: Love Test Report (opengl) - if: steps.vars.outputs.arch != 'ARM64' + id: report1 + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' uses: ellraiser/love-test-report@main with: name: Love Testsuite Windows ${{ steps.vars.outputs.arch }} ${{ steps.vars.outputs.compatname }} (opengl) @@ -321,23 +325,24 @@ jobs: path: megasource/libs/love/testing/output/lovetest_runAllTests.md token: ${{ secrets.GITHUB_TOKEN }} - name: Zip Test Output (opengl) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: | 7z a -tzip test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl.zip megasource/libs/love/testing/output/ - name: Artifact Test Output (opengl) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' uses: actions/upload-artifact@v3 with: - name: test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl - path: test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl.zip + name: test-output-windows-${{ steps.vars.outputs.arch }}-opengl-${{ steps.report1.outputs.conclusion }} + path: test-output-windows-${{ steps.vars.outputs.arch }}-opengl.zip # windows opengles tests - name: Run Tests (opengles) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: | $ENV:LOVE_GRAPHICS_USE_OPENGLES=1 powershell.exe ./install/lovec.exe ./megasource/libs/love/testing/main.lua --runAllTests --isRunner - name: Love Test Report (opengles) - if: steps.vars.outputs.arch != 'ARM64' + id: report2 + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' uses: ellraiser/love-test-report@main with: name: Love Testsuite Windows ${{ steps.vars.outputs.arch }} ${{ steps.vars.outputs.compatname }} (opengles) @@ -345,15 +350,15 @@ jobs: path: megasource/libs/love/testing/output/lovetest_runAllTests.md token: ${{ secrets.GITHUB_TOKEN }} - name: Zip Test Output (opengles) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' run: | 7z a -tzip test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles.zip megasource/libs/love/testing/output/ - name: Artifact Test Output (opengles) - if: steps.vars.outputs.arch != 'ARM64' + if: steps.vars.outputs.arch != 'ARM64' && steps.vars.outputs.compatname != '-compat' uses: actions/upload-artifact@v3 with: - name: test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles - path: test-output-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles.zip + name: test-output-windows-${{ steps.vars.outputs.arch }}-opengles-${{ steps.report2.outputs.conclusion }} + path: test-output-windows-${{ steps.vars.outputs.arch }}-opengles.zip # # install vulkan # - name: Install Vulkan # if: steps.vars.outputs.arch != 'ARM64' @@ -427,6 +432,7 @@ jobs: ls love-macos/love.app/Contents/MacOS/love ./testing/main.lua --runAllTests --isRunner - name: Love Test Report + id: report1 uses: ellraiser/love-test-report@main with: name: Love Testsuite MacOS @@ -439,7 +445,7 @@ jobs: - name: Artifact Test Output uses: actions/upload-artifact@v3 with: - name: test-output-macos-opengl + name: test-output-macos-opengl-${{ steps.report1.outputs.conclusion }} path: test-output-macos-opengl.zip iOS-Simulator: runs-on: macos-latest diff --git a/testing/main.lua b/testing/main.lua index 0e6e74e93..2b9ec38da 100644 --- a/testing/main.lua +++ b/testing/main.lua @@ -47,13 +47,16 @@ love.load = function(args) } Logo.img = love.graphics.newQuad(0, 0, 64, 64, Logo.texture) Font = love.graphics.newFont('resources/font.ttf', 8, 'normal') - TextCommand = love.graphics.newTextBatch(Font, 'Loading...') - TextRun = love.graphics.newTextBatch(Font, '') + local txtobj = love.graphics.newTextBatch or love.graphics.newText + TextCommand = txtobj(Font, 'Loading...') + TextRun = txtobj(Font, '') end end -- mount for output later - love.filesystem.mountFullPath(love.filesystem.getSource() .. "/output", "tempoutput", "readwrite") + if love.filesystem.mountFullPath then + love.filesystem.mountFullPath(love.filesystem.getSource() .. "/output", "tempoutput", "readwrite") + end -- get all args with any comma lists split out as seperate local arglist = {} diff --git a/testing/output/expected/love.test.graphics.ParticleSystem-1.png b/testing/output/expected/love.test.graphics.ParticleSystem-1.png new file mode 100644 index 0000000000000000000000000000000000000000..401a2ef39f892ba26e1d35594d7b95233f01c69d GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`a0d8 2 then + contact:setEnabled(false) + end + end, function() end + ) + world:update(1) + test:assertEquals(true, collided, 'check bodies collided') + -- update again for enabled check + world:update(1) + test:assertEquals(2, pass, 'check ran twice') end @@ -52,10 +245,131 @@ love.test.physics.Joint = function(test) end +--love.test.physics.Test1 = function(test) +-- local world = love.physics.newWorld(0, 0, false) +-- local body1 = love.physics.newBody(world, 0, 0, 'dynamic') +-- local shape1 = love.physics.newRectangleShape(body1, 5, 5, 10, 10) +-- local tlx, tly, brx, bry = shape1:getBoundingBox(1) +-- print('position:', tlx, tly, brx, bry) -- (-0.3, -0.3, 10.3, 10.3) +-- test:assertEquals(true, shape1:testPoint(5, 5), 'check point 1') -- returns false +--end + + -- Shape (love.physics.newCircleShape) --- @NOTE includes Fixture methods too now so enjoy +-- @NOTE in 12.0 fixtures have been merged into shapes love.test.physics.Shape = function(test) - test:skipTest('test class needs writing') + -- create shape + local world = love.physics.newWorld(0, 0, false) + local body1 = love.physics.newBody(world, 0, 0, 'dynamic') + local shape1 = love.physics.newRectangleShape(body1, 5, 5, 10, 10) + test:assertObject(shape1) + -- check base properties + test:assertEquals(1, shape1:getChildCount(), 'check child count') + test:assertEquals(0, math.floor(shape1:getRadius()), 'check radius') + test:assertEquals('polygon', shape1:getType(), 'check rectangle type') + test:assertEquals(0, shape1:getBody():getX(), 'check body link') + test:assertEquals(1, shape1:getCategory(), 'check def category') + shape1:setCategory(3, 5, 6) + local categories = {shape1:getCategory()} + test:assertEquals(14, categories[1] + categories[2] + categories[3], 'check set category') + test:assertEquals(false, shape1:isSensor(), 'check sensor def') + shape1:setSensor(true) + test:assertEquals(true, shape1:isSensor(), 'check set sensor') + shape1:setSensor(false) + test:assertEquals(false, shape1:isDestroyed(), 'check not destroyed') + test:assertEquals(nil, shape1:getUserData(), 'check no user data') + shape1:setUserData({ test = 14 }) + test:assertEquals(14, shape1:getUserData().test, 'check user data set') + -- check bounding box + -- polygons have an additional skin radius to help with collisions + -- so this wont be 0, 0, 10, 10 as you'd think but has an additional 0.3 padding + local topLeftX, topLeftY, bottomRightX, bottomRightY = shape1:computeAABB(0, 0, 0, 1) + local tlx, tly, brx, bry = shape1:getBoundingBox(1) + test:assertEquals(topLeftX, tlx, 'check bbox methods match tlx') + test:assertEquals(topLeftY, tly, 'check bbox methods match tly') + test:assertEquals(bottomRightX, brx, 'check bbox methods match brx') + test:assertEquals(bottomRightY, bry, 'check bbox methods match bry') + test:assertEquals(topLeftX, topLeftY, 'check bbox tl 1') + test:assertEquals(-3, math.floor(topLeftY*10), 'check bbox tl 2') + test:assertEquals(bottomRightX, bottomRightY, 'check bbox br 1') + test:assertEquals(10, math.floor(bottomRightX), 'check bbox br 2') + -- check physics props + test:assertEquals(1, shape1:getDensity(), 'check def density') + shape1:setDensity(5) + test:assertEquals(5, shape1:getDensity(), 'check set density') + local x, y, mass, inertia = shape1:getMassData() + test:assertEquals(5, math.floor(x), 'check shape mass pos x') + test:assertEquals(5, math.floor(y), 'check shape mass pos y') + test:assertEquals(5, math.floor(mass*10), 'check mass at 1 density') + test:assertEquals(0, math.floor(inertia*10), 'check intertia at 1 density') + x, y, mass, inertia = shape1:computeMass(1000) + test:assertEquals(111, math.floor(mass), 'check mass at 1000 density') + test:assertEquals(7407, math.floor(inertia), 'check intertia at 1000 density') + test:assertEquals(2, math.floor(shape1:getFriction()*10), 'check def friction') + shape1:setFriction(1) + test:assertEquals(1, shape1:getFriction(), 'check set friction') + test:assertEquals(0, shape1:getRestitution(), 'check def restitution') + shape1:setRestitution(0.5) + test:assertEquals(5, math.floor(shape1:getRestitution()*10), 'check set restitution') + -- check points + local shape2 = love.physics.newRectangleShape(body1, 5, 5, 10, 10) + tlx, tly, brx, bry = shape2:getBoundingBox(1) + test:assertEquals(true, shape2:testPoint(5, 5), 'check point 5,5') + test:assertEquals(true, shape2:testPoint(15, 15, 10, 10, 0), 'check point 15,15 after translate 10,10') + test:assertEquals(true, shape2:testPoint(15, 15, 10, 10, 90), 'check point 15,15 after translate 10,10,90') + test:assertEquals(false, shape2:testPoint(5, 5, 10, 10, 90), 'check point 5,5 after translate 10,10,90') + test:assertEquals(false, shape2:testPoint(15, 15), 'check point 15,15') + local xn, yn, fraction = shape2:rayCast(-20, -20, 20, 20, 100, 0, 0, 0, 1) + test:assertNotEquals(nil, xn, 'check ray 1 x') + test:assertNotEquals(nil, xn, 'check ray 1 y') + xn, yn, fraction = shape2:rayCast(10, 10, -150, -150, 100, 0, 0, 0, 1) + test:assertEquals(nil, xn, 'check ray 2 x') + test:assertEquals(nil, xn, 'check ray 2 y') + -- check filtering + test:assertEquals(nil, shape2:getMask(), 'check no mask') + shape2:setMask(1, 2, 3) + test:assertEquals(3, #{shape2:getMask()}, 'check set mask') + test:assertEquals(0, shape2:getGroupIndex(), 'check no index') + shape2:setGroupIndex(-1) + test:assertEquals(-1, shape2:getGroupIndex(), 'check set index') + local cat, mask, group = shape2:getFilterData() + test:assertEquals(1, cat, 'check filter cat') + test:assertEquals(65528, mask, 'check filter mask') + test:assertEquals(-1, group, 'check filter group') + -- run some collision checks using filters + shape1:destroy() + test:assertEquals(true, shape1:isDestroyed(), 'check destroyed') + shape2:destroy() + local body2 = love.physics.newBody(world, 5, 5, 'dynamic') + local shape3 = love.physics.newRectangleShape(body1, 0, 0, 10, 10) + local shape4 = love.physics.newRectangleShape(body2, 0, 0, 10, 10) + local collisions = 0 + world:setCallbacks( + function() collisions = collisions + 1 end, + function() end, + function() end, + function() end + ) + -- same group will always collide if the group is positive or never collide if it's negative + shape3:setGroupIndex(1) + shape4:setGroupIndex(1) + world:update(1) + test:assertEquals(1, collisions, 'check positive group collide') + shape3:setGroupIndex(-1) + shape4:setGroupIndex(-1) + body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1) + test:assertEquals(1, collisions, 'check negative group collide') + -- mask sets which categories this fixture should NOT collide with. + shape3:setGroupIndex(0) + shape4:setGroupIndex(0) + shape3:setCategory(2) + shape4:setMask(3) + body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1) + test:assertEquals(2, collisions, 'check mask collide') + shape3:setCategory(2) + shape4:setMask(2, 4, 6) + body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1) + test:assertEquals(2, collisions, 'check mask not collide') end