finished a bunch of modules

- finished audio module
- finished data module
- finished filesystem module
- finished font module (note: glphy test fails, but seems to be a 12.0 issue)
- finished image module
- finished maths module
- finished sound module
- finished thread module
- finished video module
- fixed pcall error not showing in results for invalid test code
This commit is contained in:
ell
2023-10-14 18:18:53 +01:00
parent f477b8085f
commit 09d0ace4b6
27 changed files with 2169 additions and 1263 deletions
+149 -28
View File
@@ -3,8 +3,10 @@ on: [push, pull_request]
jobs:
linux-os:
runs-on: ubuntu-20.04
timeout-minutes: 60
runs-on: ubuntu-22.04
env:
ALSOFT_CONF: resources/alsoft.conf
DISPLAY: :99
steps:
- name: Update APT
run: sudo apt-get update
@@ -16,7 +18,9 @@ jobs:
libxfixes-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev \
libgl1-mesa-dev libdbus-1-dev libudev-dev libgles2-mesa-dev \
libegl1-mesa-dev libibus-1.0-dev fcitx-libs-dev libsamplerate0-dev \
libsndio-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev
libsndio-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev \
libfuse2 wmctrl openbox mesa-vulkan-drivers libvulkan1 vulkan-tools \
vulkan-validationlayers
- name: Checkout love-appimage-source
uses: actions/checkout@v3
with:
@@ -55,17 +59,82 @@ jobs:
chmod a+x love-${{ github.sha }}.AppImage
echo "ready to run"
ls
- name: Run All Tests
- name: Start xvfb and openbox
run: |
echo "Starting XVFB on $DISPLAY"
Xvfb $DISPLAY -screen 0, 360x240x24 &
echo "XVFBPID=$!" >> $GITHUB_ENV
# wait for xvfb to startup (3s is the same amount xvfb-run waits by default)
sleep 3
openbox &
echo "OPENBOXPID=$!" >> $GITHUB_ENV
# linux opengl tests
- name: Run All Tests (opengl)
run: xvfb-run ./love-${{ github.sha }}.AppImage ./testing/main.lua
- name: Love Test Report
- name: Love Test Report (opengl)
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Linux
title: linux-test-report
title: test-report-linux-opengl
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (opengl)
run: |
7z a -tzip test-output-linux-opengl.zip testing/output/
- name: Artifact Test Output (opengl)
uses: actions/upload-artifact@v3
with:
name: test-output-linux-opengl
path: test-output-linux-opengl.zip
# linux opengles tests
- name: Run Test Suite (opengles)
run: |
export LOVE_GRAPHICS_USE_OPENGLES=1
xvfb-run ./love-${{ github.sha }}.AppImage ./testing/main.lua
- name: Love Test Report (opengles)
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Linux
title: test-report-linux-opengles
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (opengles)
run: |
7z a -tzip test-output-linux-opengles.zip testing/output/
- name: Artifact Test Output (opengles)
uses: actions/upload-artifact@v3
with:
name: test-output-linux-opengles
path: test-output-linux-opengles.zip
# linux vulkan tests
- name: Run Test Suite (vulkan)
run: |
export LOVE_GRAPHICS_DEBUG=1
xvfb-run ./love-${{ github.sha }}.AppImage ./testing/main.lua --runAllTests --renderers vulkan
- name: Love Test Report (vulkan)
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Linux
title: test-report-linux-vulkan
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (vulkan)
run: |
7z a -tzip test-output-linux-vulkan.zip testing/output/
- name: Artifact Test Output (vulkan)
uses: actions/upload-artifact@v3
with:
name: test-output-linux-vulkan
path: test-output-linux-vulkan.zip
- name: Stop xvfb and openbox
# should always stop xvfb and openbox even if other steps failed
if: always()
run: |
kill $XVFBPID
kill $OPENBOXPID
windows-os:
runs-on: windows-latest
timeout-minutes: 60
env:
ALSOFT_CONF: resources/alsoft.conf
VK_ICD_FILENAMES: ${{ github.workspace }}\mesa\x64\lvp_icd.x86_64.json
VULKAN_SDK: C:/VulkanSDK/1.3.231.1
strategy:
matrix:
platform: [Win32, x64, ARM64]
@@ -220,19 +289,6 @@ jobs:
with:
name: love-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-dbg
path: pdb/Release/*.pdb
- name: Install Scream
shell: powershell
run: |
Start-Service audio*
Invoke-WebRequest https://github.com/duncanthrax/scream/releases/download/3.6/Scream3.6.zip -OutFile C:\Scream3.6.zip
Extract-7Zip -Path C:\Scream3.6.zip -DestinationPath C:\Scream
$cert = (Get-AuthenticodeSignature C:\Scream\Install\driver\Scream.sys).SignerCertificate
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPublisher", "LocalMachine")
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()
cd C:\Scream\Install\driver
C:\Scream\Install\helpers\devcon install Scream.inf *Scream
- name: Install Mesa
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
@@ -241,21 +297,78 @@ jobs:
- name: Build Test Exe
if: steps.vars.outputs.arch != 'ARM64'
run: cmake --build build --config Release --target install
- name: Run All Tests
- name: Run Tests (opengl)
if: steps.vars.outputs.arch != 'ARM64'
run: |
dir
powershell.exe ./install/lovec.exe ./testing/main.lua
- name: Love Test Report
# windows opengl test
- name: Love Test Report (opengl)
if: steps.vars.outputs.arch != 'ARM64'
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Windows
title: windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-test-report
name: Love Testsuite Windows (opengl)
title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (opengl)
run: |
7z a -tzip test-output-windows-opengl.zip testing/output/
- name: Artifact Test Output (opengl)
uses: actions/upload-artifact@v3
with:
name: test-output-windows-opengl
path: test-output-windows-opengl.zip
# windows opengles test
- name: Run Tests (opengles)
run: |
$ENV:LOVE_GRAPHICS_USE_OPENGLES=1
powershell.exe ./install/lovec.exe ./testing/main.lua
- name: Love Test Report (opengles)
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Windows (opengles)
title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (opengles)
run: |
7z a -tzip test-output-windows-opengles.zip testing/output/
- name: Artifact Test Output (opengles)
uses: actions/upload-artifact@v3
with:
name: test-output-windows-opengles
path: test-output-windows-opengles.zip
- name: Install Vulkan
run: |
curl -L --show-error --output VulkanSDK.exe https://sdk.lunarg.com/sdk/download/1.3.231.1/windows/VulkanSDK-1.3.231.1-Installer.exe
./VulkanSDK.exe --root C:/VulkanSDK/1.3.231.1 --accept-licenses --default-answer --confirm-command install com.lunarg.vulkan.core com.lunarg.vulkan.vma
curl -L --show-error --output vulkan-runtime.zip https://sdk.lunarg.com/sdk/download/1.3.231.1/windows/vulkan-runtime-components.zip
7z e vulkan-runtime.zip -o"C:/VulkanSDK/1.3.231.1/runtime/x64" */x64
copy "C:/VulkanSDK/1.3.231.1/runtime/x64/vulkan-1.dll" "mesa/x64"
copy "C:/VulkanSDK/1.3.231.1/runtime/x64/vulkan-1.dll" "C:/Windows/System32"
copy "C:/VulkanSDK/1.3.231.1/runtime/x64/vulkan-1.dll" "love-12.0-win64/love-12.0-win64"
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers /v "${{ github.workspace }}\mesa\x64\lvp_icd.x86_64.json" /t REG_DWORD /d 0
powershell.exe C:/VulkanSDK/1.3.231.1/runtime/x64/vulkaninfo.exe --summary
# windows vulkan tests
- name: Run Tests (vulkan)
run: |
$ENV:LOVE_GRAPHICS_DEBUG=1
powershell.exe ./install/lovec.exe ./testing/main.lua --runAllTests --renderers vulkan
- name: Love Test Report (vulkan)
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite Windows (vulkan)
title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-vulkan
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output (vulkan)
run: |
7z a -tzip test-output-windows-vulkan.zip testing/output
- name: Artifact Test Output (vulkan)
uses: actions/upload-artifact@v3
with:
name: test-output-windows-vulkan
path: test-output-windows-vulkan.zip
macOS:
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -282,17 +395,25 @@ jobs:
with:
name: love-macos
path: love-macos.zip
- name: Run All Tests
# macos opengl tests
- name: Run Tests
run: love-macos/love.app/Contents/MacOS/love testing/main.lua
- name: Love Test Report
uses: ellraiser/love-test-report@main
with:
name: Love Testsuite MacOS
title: macos-test-report
title: test-report-macos
path: testing/output/lovetest_runAllTests.md
- name: Zip Test Output
run: |
7z a -tzip test-output-macos-opengl.zip testing/output/
- name: Artifact Test Output
uses: actions/upload-artifact@v3
with:
name: test-output-macos-opengl
path: test-output-macos-opengl.zip
iOS-Simulator:
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v3
+49 -16
View File
@@ -41,7 +41,8 @@ TestMethod = {
},
imgs = 1,
delay = 0,
delayed = false
delayed = false,
store = {}
}
setmetatable(test, self)
self.__index = self
@@ -58,11 +59,11 @@ TestMethod = {
assertEquals = function(self, expected, actual, label)
self.count = self.count + 1
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = expected == actual,
message = 'expected \'' .. tostring(expected) .. '\' got \'' ..
tostring(actual) .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -109,11 +110,11 @@ TestMethod = {
assertNotEquals = function(self, expected, actual, label)
self.count = self.count + 1
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = expected ~= actual,
message = 'avoiding \'' .. tostring(expected) .. '\' got \'' ..
tostring(actual) .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -128,11 +129,11 @@ TestMethod = {
assertRange = function(self, actual, min, max, label)
self.count = self.count + 1
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = actual >= min and actual <= max,
message = 'value \'' .. tostring(actual) .. '\' out of range \'' ..
tostring(min) .. '-' .. tostring(max) .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -150,11 +151,11 @@ TestMethod = {
if list[l] == actual then found = true end;
end
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = found == true,
message = 'value \'' .. tostring(actual) .. '\' not found in \'' ..
table.concat(list, ',') .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -172,11 +173,11 @@ TestMethod = {
passing = actual >= target
end
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = passing,
message = 'value \'' .. tostring(actual) .. '\' not >= \'' ..
tostring(target) .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -194,11 +195,11 @@ TestMethod = {
passing = actual <= target
end
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = passing,
message = 'value \'' .. tostring(actual) .. '\' not <= \'' ..
tostring(target) .. '\'',
test = label
test = label or 'no label given'
})
end,
@@ -206,7 +207,7 @@ TestMethod = {
-- @method - TestMethod:assertObject()
-- @desc - used to check a table is a love object, this runs 3 seperate
-- tests to check table has the basic properties of an object
-- @note - actual object functionality tests are done in the objects module
-- @note - actual object functionality tests have their own methods
-- @param {table} obj - table to check is a valid love object
-- @return {nil}
assertObject = function(self, obj)
@@ -218,6 +219,29 @@ TestMethod = {
end,
-- @method - TestMethod:assertCoords()
-- @desc - used to check a pair of values (usually coordinates)
-- @param {table} obj - table to check is a valid love object
-- @return {nil}
assertCoords = function(self, expected, actual, label)
self.count = self.count + 1
local passing = false
if expected ~= nil and actual ~= nil then
if expected[1] == actual[1] and expected[2] == actual[2] then
passing = true
end
end
table.insert(self.asserts, {
key = 'assert ' .. tostring(self.count),
passed = passing,
message = 'expected \'' .. tostring(expected[1]) .. 'x,' ..
tostring(expected[2]) .. 'y\' got \'' ..
tostring(actual[1]) .. 'x,' .. tostring(actual[2]) .. 'y\'',
test = label or 'no label given'
})
end,
-- @method - TestMethod:assertNotNil()
-- @desc - quick assert for value not nil
-- @param {any} value - value to check not nil
@@ -226,7 +250,7 @@ TestMethod = {
self:assertNotEquals(nil, value, 'check not nil')
if err ~= nil then
table.insert(self.asserts, {
key = 'assert #' .. tostring(self.count),
key = 'assert ' .. tostring(self.count),
passed = false,
message = err,
test = 'assert not nil catch'
@@ -235,6 +259,10 @@ TestMethod = {
end,
-- @method - TestMethod:exportImg()
-- @desc - used to export actual test img results to compare to the expected
-- @param {table} imgdata - imgdata to save as a png
-- @return {nil}
exportImg = function(self, imgdata)
local path = 'tempoutput/actual/love.test.graphics.' ..
self.method .. '-' .. tostring(self.imgs) .. '.png'
@@ -320,12 +348,17 @@ TestMethod = {
if failure['test'] ~= nil then
key = key .. ' [' .. failure['test'] .. ']'
end
local msg = failure['message']
if self.fatal ~= '' then
key = 'code'
msg = self.fatal
end
self.result = {
total = total,
result = 'FAIL',
passed = false,
key = key,
message = failure['message']
message = msg
}
end
end
+5 -6
View File
@@ -35,7 +35,6 @@ TestSuite = {
joystick = {},
math = {},
mouse = {},
objects = {}, -- special for all object class contructor tests
physics = {},
sound = {},
system = {},
@@ -76,7 +75,7 @@ TestSuite = {
TextRun:set('love.' .. self.module.module .. '.' .. method)
-- check method exists in love first
if self.module.module ~= 'objects' and (love[self.module.module] == nil or love[self.module.module][method] == nil) then
if love[self.module.module] == nil then
local tested = 'love.' .. self.module.module .. '.' .. method .. '()'
local matching = string.sub(self.module.spacer, string.len(tested), 40)
self.module:log(self.module.colors['FAIL'],
@@ -87,7 +86,7 @@ TestSuite = {
else
local ok, chunk, err = pcall(self[self.module.module][method], self.test)
if ok == false then
print("FATAL", chunk, err)
self.test.passed = false
self.test.fatal = tostring(chunk) .. tostring(err)
end
end
@@ -105,7 +104,7 @@ TestSuite = {
if self.delayed.delay <= 0 then
local ok, chunk, err = pcall(self[self.module.module][self.delayed.method], self.test)
if ok == false then
print("FATAL", chunk, err)
self.test.passed = false
self.test.fatal = tostring(chunk) .. tostring(err)
end
self.delayed = nil
@@ -115,7 +114,7 @@ TestSuite = {
-- now we're all done evaluate the test
local ok, chunk, err = pcall(self.test.evaluateTest, self.test)
if ok == false then
print("FATAL", chunk, err)
self.test.passed = false
self.test.fatal = tostring(chunk) .. tostring(err)
end
-- save having to :release() anything we made in the last test
@@ -169,7 +168,7 @@ TestSuite = {
tostring(self.totals[1]) .. '** passed, **' ..
tostring(self.totals[2]) .. '** failed, and **' ..
tostring(self.totals[3]) .. '** skipped\n\n### Report\n' ..
'| Module | Passed | Failed | Skipped | Time |\n' ..
'| Module | Pass | Fail | Skip | Time |\n' ..
'| --------------------- | ------ | ------ | ------- | ------ |\n' ..
self.mdrows .. '\n\n### Failures\n' .. self.mdfailures
File diff suppressed because one or more lines are too long
+20 -18
View File
@@ -1,26 +1,28 @@
<!-- PASSED 244 || FAILED 0 || SKIPPED 61 || TIME 37.853 -->
<!-- PASSED 254 || FAILED 1 || SKIPPED 50 || TIME 12.195 -->
**305** tests were completed in **37.853s** with **244** passed, **0** failed, and **61** skipped
**305** tests were completed in **12.195s** with **254** passed, **1** failed, and **50** skipped
### Report
| Module | Passed | Failed | Skipped | Time |
| --------------------- | ------ | ------ | ------- | ------ |
| 🟢 love.audio | 26 | 0 | 0 | 2.605s |
| 🟢 love.data | 7 | 0 | 3 | 1.003s |
| 🟢 love.event | 4 | 0 | 2 | 0.600s |
| 🟢 love.filesystem | 27 | 0 | 2 | 3.030s |
| 🟢 love.font | 4 | 0 | 1 | 0.511s |
| 🟢 love.graphics | 81 | 0 | 15 | 10.599s |
| 🟢 love.image | 3 | 0 | 0 | 0.299s |
| 🟢 love.math | 17 | 0 | 0 | 1.821s |
| 🟢 love.objects | 1 | 0 | 34 | 3.603s |
| 🟢 love.physics | 22 | 0 | 0 | 2.222s |
| 🟢 love.sound | 2 | 0 | 0 | 0.199s |
| 🟢 love.system | 6 | 0 | 2 | 0.844s |
| 🟢 love.thread | 3 | 0 | 0 | 0.318s |
| 🟢 love.timer | 6 | 0 | 0 | 2.309s |
| 🟢 love.video | 1 | 0 | 0 | 0.114s |
| 🟢 love.window | 34 | 0 | 2 | 7.778s |
| 🟢 audio | 26 | 0 | 2 | 0.473s |
| 🟢 data | 7 | 0 | 5 | 0.212s |
| 🟢 event | 4 | 0 | 2 | 0.108s |
| 🟢 filesystem | 28 | 0 | 3 | 0.556s |
| 🟢 font | 4 | 0 | 3 | 0.127s |
| 🔴 graphics | 91 | 1 | 15 | 2.091s |
| 🟢 image | 3 | 0 | 2 | 0.087s |
| 🟢 math | 17 | 0 | 3 | 0.358s |
| 🟢 physics | 22 | 0 | 6 | 0.492s |
| 🟢 sound | 2 | 0 | 2 | 0.072s |
| 🟢 system | 6 | 0 | 2 | 0.142s |
| 🟢 thread | 3 | 0 | 2 | 0.088s |
| 🟢 timer | 6 | 0 | 0 | 2.086s |
| 🟢 video | 1 | 0 | 1 | 0.031s |
| 🟢 window | 34 | 0 | 2 | 5.273s |
### Failures
> 🔴 setColorMask
> assert #7 [check pixel b for yellow at 0,0(set color mask)] expected '0' got '1'
File diff suppressed because it is too large Load Diff
+21 -7
View File
@@ -1,5 +1,5 @@
-- & 'c:\Program Files\LOVE\love.exe' ./ --console
-- /Applications/love.app/Contents/MacOS/love ./
-- /Applications/love_12.app/Contents/MacOS/love ./testing
-- load test objs
require('classes.TestSuite')
@@ -25,7 +25,6 @@ if love.thread ~= nil then require('tests.thread') end
if love.timer ~= nil then require('tests.timer') end
if love.video ~= nil then require('tests.video') end
if love.window ~= nil then require('tests.window') end
require('tests.objects')
-- love.load
-- load given arguments and run the test suite
@@ -72,21 +71,21 @@ love.load = function(args)
local cmderr = 'Invalid flag used'
local modules = {
'audio', 'data', 'event', 'filesystem', 'font', 'graphics',
'image', 'math', 'objects', 'physics', 'sound', 'system',
'image', 'math', 'physics', 'sound', 'system',
'thread', 'timer', 'video', 'window'
}
GITHUB_RUNNER = false
for a=1,#arglist do
if testcmd == '--runSpecificMethod' then
if module == '' and love[ arglist[a] ] ~= nil then
module = arglist[a]
table.insert(modules, module)
end
if module ~= '' and love[module][ arglist[a] ] ~= nil and method == '' then
method = arglist[a]
elseif module ~= '' and love[module] ~= nil and method == '' then
if love.test[module][arglist[a]] ~= nil then method = arglist[a] end
end
end
if testcmd == '--runSpecificModules' then
if love[ arglist[a] ] ~= nil or arglist[a] == 'objects' then
if love[ arglist[a] ] ~= nil and arglist[a] ~= '--isRunner' then
table.insert(modules, arglist[a])
end
end
@@ -98,6 +97,9 @@ love.load = function(args)
testcmd = arglist[a]
modules = {}
end
if arglist[a] == '--isRunner' then
GITHUB_RUNNER = true
end
end
-- runSpecificMethod uses the module + method given
@@ -142,6 +144,10 @@ love.load = function(args)
love.test.output = 'lovetest_runAllTests'
end
if GITHUB_RUNNER then
love.test.module:log('grey', '--isRunner')
end
-- invalid command
if love.test.module == nil then
print(cmderr)
@@ -183,6 +189,10 @@ love.quit = function()
end
-- added so bad threads dont fail
function love.threaderror(thread, errorstr) end
-- string split helper
function UtilStringSplit(str, splitter)
local splits = {}
@@ -197,3 +207,7 @@ end
function UtilTimeFormat(seconds)
return string.format("%.3f", tostring(seconds))
end
function UtilDebugLog(a, b, c)
if GITHUB_RUNNER == true then print("DEBUG ==> ", a, b, c) end
end
+57 -60
View File
@@ -1,60 +1,87 @@
# löve.test
Basic testing suite for the löve APIs, based off of [this issue](https://github.com/love2d/love/issues/1745)
# Lövetest
Basic testing suite for the [Löve](https://github.com/love2d/love) APIs, based off of [this issue](https://github.com/love2d/love/issues/1745).
Currently written for löve 12
Currently written for [Löve 12](https://github.com/love2d/love/tree/12.0-development), which is still in development.
---
## Primary Goals
## Features
- [x] Simple pass/fail tests in Lua with minimal setup
- [x] Ability to run all tests with a simple command.
- [x] Ability to run all tests with a simple command
- [x] Ability to see how many tests are passing/failing
- [x] No platform-specific dependencies / scripts
- [x] Ability to run a subset of tests
- [x] Ability to easily run an individual test.
- [x] Ability to easily run an individual test
- [x] Ability to see all visual results at a glance
- [x] Automatic testing that happens after every commit
- [x] No platform-specific dependencies / scripts
---
## Coverage
This is the status of all module tests currently.
| Module | Done | Todo | Skip |
| ----------------- | ---- | ---- | ---- |
| 🟢 audio | 28 | 0 | 0 |
| 🟢 data | 12 | 0 | 0 |
| 🟡 event | 4 | 1 | 1 |
| 🟢 filesystem | 28 | 0 | 2 |
| 🟢 font | 7 | 0 | 0 |
| 🟡 graphics | 93 | 14 | 1 |
| 🟢 image | 5 | 0 | 0 |
| 🟢 math | 20 | 0 | 0 |
| 🟡 physics | 22 | 6 | 0 |
| 🟢 sound | 4 | 0 | 0 |
| 🟢 system | 6 | 0 | 2 |
| 🟢 thread | 5 | 0 | 0 |
| 🟢 timer | 6 | 0 | 0 |
| 🟢 video | 2 | 0 | 0 |
| 🟢 window | 34 | 0 | 2 |
> The following modules are not covered as we can't really emulate input nicely:
> `joystick`, `keyboard`, `mouse`, and `touch`
---
## Running Tests
The initial pass is to keep things as simple as possible, and just run all the tests inside Löve to match how they'd be used by developers in-engine.
To run the tests, download the repo and then run the main.lua as you would a löve game, i.e:
The testsuite aims to keep things as simple as possible, and just runs all the tests inside Löve to match how they'd be used by developers in-engine.
To run the tests, download the repo and then run the main.lua as you would a Löve game, i.e:
WINDOWS: `& 'c:\Program Files\LOVE\love.exe' PATH_TO_TESTING_FOLDER --console`
MACOS: `/Applications/love.app/Contents/MacOS/love PATH_TO_TESTING_FOLDER`
MACOS: `/Applications/love.app/Contents/MacOS/love PATH_TO_TESTING_FOLDER`
LINUX: `./love.AppImage PATH_TO_TESTING_FOLDER`
By default all tests will be run for all modules.
If you want to specify a module you can add:
`--runSpecificModules filesystem`
For multiple modules, provide a comma seperate list:
`--runSpecificModules filesystem,audio,data"`
If you want to specify a module/s you can use:
`--runSpecificModules filesystem,audio`
If you want to specify only 1 specific method only you can use:
`--runSpecificMethod filesystem write`
All results will be printed in the console per method as PASS, FAIL, or SKIP with total assertions met on a module level and overall level.
An `XML` file in the style of [JUnit XML](https://www.ibm.com/docs/en/developer-for-zos/14.1?topic=formats-junit-xml-format) will be generated in the `/output` directory, along with a `HTML` and a `Markdown` file with a summary of all tests (including visuals for love.graphics tests).
> An example of both types of output can be found in the `/examples` folder
The Markdown file can be used with [this github action](https://github.com/ellraiser/love-test-report) if you want to output the report results to your CI.
When finished, the following files will be generated in the `/output` directory with a summary of the test results:
- an `XML` file in the style of [JUnit XML](https://www.ibm.com/docs/en/developer-for-zos/14.1?topic=formats-junit-xml-format)
- a `HTML` file that shows any visual test results
- a `Markdown` file for use with [this github action](https://github.com/ellraiser/love-test-report)
> An example of all types of output can be found in the `/examples`
> The visual results of any graphic tests can be found in `/output/actual`
---
## Architecture
Each method has it's own test method written in `/tests` under the matching module name.
Each method and object has it's own test method written in `/tests` under the matching module name.
When you run the tests, a single TestSuite object is created which handles the progress + totals for all the tests.
Each module has a TestModule object created, and each test method has a TestMethod object created which keeps track of assertions for that method. You can currently do the following assertions:
- **assertNotNil**(value)
- **assertEquals**(expected, actual)
- **assertNotEquals**(expected, actual)
- **assertRange**(actual, min, max)
- **assertMatch**({option1, option2, option3 ...}, actual)
- **assertGreaterEqual**(expected, actual)
- **assertLessEqual**(expected, actual)
- **assertEquals**(expected, actual, label)
- **assertNotEquals**(expected, actual, label)
- **assertRange**(actual, min, max, label)
- **assertMatch**({option1, option2, option3 ...}, actual, label)
- **assertGreaterEqual**(expected, actual, label)
- **assertLessEqual**(expected, actual, label)
- **assertObject**(table)
- **assertPixels**(imgdata, pixeltable, label)
- **assertCoords**(expected, actual, label)
Example test method:
```lua
@@ -76,52 +103,22 @@ end
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)
For sanity-checking, if it's currently not covered or we're not sure how to test yet we can set the test to be skipped with `test:skipTest(reason)` - this way we still see the method listed in the tests without it affected the pass/fail totals
---
## Coverage
This is the status of all module tests currently.
| Module | Passed | Failed | Skipped | Time |
| --------------------- | ------ | ------ | ------- | ------ |
| 🟢 love.audio | 26 | 0 | 0 | 2.602s |
| 🟢 love.data | 7 | 0 | 3 | 1.003s |
| 🟢 love.event | 4 | 0 | 2 | 0.599s |
| 🟢 love.filesystem | 27 | 0 | 2 | 2.900s |
| 🟢 love.font | 4 | 0 | 1 | 0.500s |
| 🟢 love.graphics | 81 | 0 | 15 | 10.678s |
| 🟢 love.image | 3 | 0 | 0 | 0.300s |
| 🟢 love.math | 17 | 0 | 0 | 1.678s |
| 🟢 love.physics | 22 | 0 | 0 | 2.197s |
| 🟢 love.sound | 2 | 0 | 0 | 0.200s |
| 🟢 love.system | 6 | 0 | 2 | 0.802s |
| 🟢 love.thread | 3 | 0 | 0 | 0.300s |
| 🟢 love.timer | 6 | 0 | 0 | 2.358s |
| 🟢 love.video | 1 | 0 | 0 | 0.100s |
| 🟢 love.window | 34 | 0 | 2 | 8.050s |
The following modules are not covered as we can't really emulate input nicely:
`joystick`, `keyboard`, `mouse`, and `touch`
For sanity-checking, if it's currently not covered or it's not possible to test the method we can set the test to be skipped with `test:skipTest(reason)` - this way we still see the method listed in the test output without it affected the pass/fail totals
---
## Todo
Modules with some small bits needed or needing sense checking:
- **love.data** - packing methods need writing cos i dont really get what they are
- **love.event** - love.event.wait or love.event.pump need writing if possible I dunno how to check
- **love.font** - newBMFontRasterizer() wiki entry is wrong so not sure whats expected
- **love.graphics** - still need to do tests for the main drawing methods
- **love.image** - ideally isCompressed should have an example of all compressed files love can take
- **love.math** - linearToGamma + gammaToLinear using direct formulas don't get same value back
- **love.*.objects** - all objects tests still to be done
- **love.graphics.setStencilTest** - deprecated, replaced by setStencilMode()
---
## Stretch Goals
- [ ] Tests can compare visual results to a reference image
- [ ] Ability to see all visual results at a glance
## Future Goals
- [ ] Tests can compare visual results to a reference image (partially done)
- [ ] Ability to test loading different combinations of modules
- [ ] Performance tests
There is some unused code in the Test.lua class to add preview vs actual images to the HTML output
+4
View File
@@ -0,0 +1,4 @@
[general]
drivers = wave
[wave]
file = output.wav
Binary file not shown.
+168 -2
View File
@@ -1,6 +1,172 @@
-- love.audio
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- RecordingDevice (love.audio.getRecordingDevices)
love.test.audio.RecordingDevice = function(test)
-- check devices first
local devices = love.audio.getRecordingDevices()
if #devices == 0 then
return test:skipTest('cant test this works: no recording devices found')
end
-- test device
if test:isDelayed() == false then
-- check object created and basics
local device = devices[1]
test.store.device = device
test:assertObject(device)
test:assertMatch({1, 2}, device:getChannelCount(), 'check channel count is 1 or 2')
test:assertNotEquals(nil, device:getName(), 'check has name')
-- check initial data is empty as we haven't recorded anything yet
test:assertNotNil(device:getBitDepth())
test:assertEquals(nil, device:getData(), 'check initial data empty')
test:assertEquals(0, device:getSampleCount(), 'check initial sample empty')
test:assertNotNil(device:getSampleRate())
test:assertEquals(false, device:isRecording(), 'check not recording')
-- start recording for a short time
local startrecording = device:start(32000, 4000, 16, 1)
test:assertEquals(true, startrecording, 'check recording started')
test:assertEquals(true, device:isRecording(), 'check now recording')
test:assertEquals(4000, device:getSampleRate(), 'check sample rate set')
test:assertEquals(16, device:getBitDepth(), 'check bit depth set')
test:assertEquals(1, device:getChannelCount(), 'check channel count set')
test:setDelay(20)
-- after recording
else
local device = test.store.device
local recording = device:stop()
test:assertEquals(false, device:isRecording(), 'check not recording')
test:assertEquals(nil, device:getData(), 'using stop should clear buffer')
test:assertObject(recording)
end
end
-- Source (love.audio.newSource)
love.test.audio.Source = function(test)
-- create stereo source
local stereo = love.audio.newSource('resources/click.ogg', 'static')
test:assertObject(stereo)
-- check stereo props
test:assertEquals(2, stereo:getChannelCount(), 'check stereo src')
test:assertEquals(66, math.floor(stereo:getDuration("seconds")*1000), 'check stereo seconds')
test:assertNotNil(stereo:getFreeBufferCount())
test:assertEquals('static', stereo:getType(), 'check stereo type')
-- check cloning a stereo
local clone = stereo:clone()
test:assertEquals(2, clone:getChannelCount(), 'check clone stereo src')
test:assertEquals(66, math.floor(clone:getDuration("seconds")*1000), 'check clone stereo seconds')
test:assertNotNil(clone:getFreeBufferCount())
test:assertEquals('static', clone:getType(), 'check cloned stereo type')
-- mess with stereo playing
test:assertEquals(false, stereo:isPlaying(), 'check not playing')
stereo:setLooping(true)
stereo:play()
test:assertEquals(true, stereo:isPlaying(), 'check now playing')
test:assertEquals(true, stereo:isLooping(), 'check now playing')
stereo:pause()
stereo:seek(0.01, 'seconds')
test:assertEquals(0.01, stereo:tell('seconds'), 'check seek/tell')
stereo:stop()
test:assertEquals(false, stereo:isPlaying(), 'check stopped playing')
-- check volume limits
stereo:setVolumeLimits(0.1, 0.5)
local min, max = stereo:getVolumeLimits()
test:assertEquals(1, math.floor(min*10), 'check min limit')
test:assertEquals(5, math.floor(max*10), 'check max limit')
-- @NOTE the following works as setVolumeLimits is used with set volume
-- as the BASE and then applying directional, rather than being a clamp
stereo:setVolume(1)
test:assertEquals(1, stereo:getVolume(), 'check set volume')
stereo:setVolume(0)
test:assertEquals(0, stereo:getVolume(), 'check set volume')
-- change some get/set props that can apply to stereo
stereo:setPitch(2)
test:assertEquals(2, stereo:getPitch(), 'check pitch change')
-- create mono source
local mono = love.audio.newSource('resources/clickmono.ogg', 'stream')
test:assertObject(mono)
test:assertEquals(1, mono:getChannelCount(), 'check mono src')
test:assertEquals(2927, mono:getDuration("samples"), 'check mono seconds')
test:assertEquals('stream', mono:getType(), 'check mono type')
-- check the basic get/set properties
test:assertEquals(0, mono:getAirAbsorption(), 'get air absorption')
mono:setAirAbsorption(1)
test:assertEquals(1, mono:getAirAbsorption(), 'set air absorption')
mono:setCone(0, 90*(math.pi/180), 1)
local ia, oa, ov = mono:getCone()
test:assertEquals(0, ia, 'check cone ia')
test:assertEquals(math.floor(9000*(math.pi/180)), math.floor(oa*100), 'check cone oa')
test:assertEquals(1, ov, 'check cone ov')
mono:setDirection(3, 1, -1)
local x, y, z = mono:getDirection()
test:assertEquals(3, x, 'check direction x')
test:assertEquals(1, y, 'check direction y')
test:assertEquals(-1, z, 'check direction z')
mono:setRelative(true)
test:assertEquals(true, mono:isRelative(), 'check set relative')
mono:setPosition(1, 2, 3)
x, y, z = mono:getPosition()
test:assertEquals(x, 1, 'check pos x')
test:assertEquals(y, 2, 'check pos y')
test:assertEquals(z, 3, 'check pos z')
mono:setVelocity(1, 3, 4)
x, y, z = mono:getVelocity()
test:assertEquals(x, 1, 'check velocity x')
test:assertEquals(y, 3, 'check velocity x')
test:assertEquals(z, 4, 'check velocity x')
mono:setRolloff(1)
test:assertEquals(1, mono:getRolloff(), 'check rolloff set')
-- create queue source
local queue = love.audio.newQueueableSource(44100, 16, 1, 3)
local sdata = love.sound.newSoundData(1024, 44100, 16, 1)
test:assertObject(queue)
local run = queue:queue(sdata)
test:assertEquals(true, run, 'check queued sound')
queue:stop()
-- check making a filer
local setfilter = stereo:setFilter({
type = 'lowpass',
volume = 0.5,
highgain = 0.3
})
test:assertEquals(true, setfilter, 'check filter applied')
local filter = stereo:getFilter()
test:assertEquals('lowpass', filter.type, 'check filter type')
test:assertEquals(0.5, filter.volume, 'check filter volume')
test:assertEquals(3, math.floor(filter.highgain*10), 'check filter highgain')
test:assertEquals(nil, filter.lowgain, 'check filter lowgain')
-- add an effect
local effsource = love.audio.newSource('resources/click.ogg', 'static')
love.audio.setEffect('testeffect', {
type = 'flanger',
volume = 10
})
local seteffect, err = effsource:setEffect('flanger', {
type = 'highpass',
volume = 0.3,
lowgain = 0.1
})
-- both these fail on 12 using stereo or mono, no err
test:assertEquals(true, seteffect, 'check effect was applied')
local filtersettings = effsource:getEffect('chorus', {})
test:assertNotNil(filtersettings)
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.audio.getActiveEffects
love.test.audio.getActiveEffects = function(test)
-- check we get a value
@@ -142,14 +308,14 @@ end
-- love.audio.newQueueableSource
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.audio.newQueueableSource = function(test)
test:assertObject(love.audio.newQueueableSource(32, 8, 1, 8))
end
-- love.audio.newSource
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.audio.newSource = function(test)
test:assertObject(love.audio.newSource('resources/click.ogg', 'static'))
test:assertObject(love.audio.newSource('resources/click.ogg', 'stream'))
+78 -8
View File
@@ -1,6 +1,61 @@
-- love.data
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- ByteData (love.data.newByteData)
love.test.data.ByteData = function(test)
-- create new obj
local data = love.data.newByteData('helloworld')
test:assertObject(data)
-- check properties match expected
test:assertEquals('helloworld', data:getString(), 'check data string')
test:assertEquals(10, data:getSize(), 'check data size')
-- check cloning the bytedata
local cloneddata = data:clone()
test:assertObject(cloneddata)
test:assertEquals('helloworld', cloneddata:getString(), 'check cloned data')
test:assertEquals(10, cloneddata:getSize(), 'check cloned size')
-- check pointer access if allowed
if data:getFFIPointer() ~= nil and ffi ~= nil then
local pointer = data:getFFIPointer()
local ptr = ffi.cast('uint8_t*', pointer)
local byte5 = ptr[4]
test:assertEquals('o', byte5)
end
end
-- CompressedData (love.data.compress)
love.test.data.CompressedData = function(test)
-- create new compressed data
local cdata = love.data.compress('data', 'zlib', 'helloworld', -1)
test:assertObject(cdata)
test:assertEquals('zlib', cdata:getFormat(), 'check format used')
-- check properties match expected
test:assertEquals(18, cdata:getSize())
test:assertEquals('helloworld', love.data.decompress('data', cdata):getString())
-- check cloning the data
local clonedcdata = cdata:clone()
test:assertObject(clonedcdata)
test:assertEquals('zlib', clonedcdata:getFormat())
test:assertEquals(18, clonedcdata:getSize())
test:assertEquals('helloworld', love.data.decompress('data', clonedcdata):getString())
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.data.compress
love.test.data.compress = function(test)
-- here just testing each combo 'works' - in decompress's test method
@@ -119,9 +174,13 @@ end
-- love.data.getPackedSize
-- @NOTE I don't really get what lua packing types are so skipping for now - ell
love.test.data.getPackedSize = function(test)
test:skipTest('test class needs writing')
local pack1 = love.data.getPackedSize('>xI3b')
local pack2 = love.data.getPackedSize('>I2B')
local pack3 = love.data.getPackedSize('>I4I4I4I4x')
test:assertEquals(5, pack1, 'check pack size 1')
test:assertEquals(3, pack2, 'check pack size 2')
test:assertEquals(17, pack3, 'check pack size 3')
end
@@ -145,28 +204,39 @@ end
-- love.data.newByteData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.data.newByteData = function(test)
test:assertObject(love.data.newByteData('helloworld'))
end
-- love.data.newDataView
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.data.newDataView = function(test)
test:assertObject(love.data.newDataView(love.data.newByteData('helloworld'), 0, 10))
end
-- love.data.pack
-- @NOTE I don't really get what lua packing types are so skipping for now - ell
love.test.data.pack = function(test)
test:skipTest('test class needs writing')
local packed1 = love.data.pack('string', '>I4I4I4I4', 9999, 1000, 1010, 2030)
local packed2 = love.data.pack('data', '>I4I4I4I4', 9999, 1000, 1010, 2030)
local a, b, c, d = love.data.unpack('>I4I4I4I4', packed1)
local e, f, g, h = love.data.unpack('>I4I4I4I4', packed2)
test:assertEquals(9999+9999, a+e, 'check packed 1')
test:assertEquals(1000+1000, b+f, 'check packed 2')
test:assertEquals(1010+1010, c+g, 'check packed 3')
test:assertEquals(2030+2030, d+h, 'check packed 4')
end
-- love.data.unpack
-- @NOTE I don't really get what lua packing types are so skipping for now - ell
love.test.data.unpack = function(test)
test:skipTest('test class needs writing')
local packed1 = love.data.pack('string', '>s5s4I3', 'hello', 'love', 100)
local packed2 = love.data.pack('data', '>s5I2', 'world', 20)
local a, b, c = love.data.unpack('>s5s4I3', packed1)
local d, e = love.data.unpack('>s5I2', packed2)
test:assertEquals(a .. ' ' .. d, 'hello world', 'check unpack 1')
test:assertEquals(b, 'love', 'check unpack 2')
test:assertEquals(c - e, 80, 'check unpack 3')
end
+8 -1
View File
@@ -1,6 +1,13 @@
-- love.event
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.event.clear
love.test.event.clear = function(test)
-- push some events first
@@ -35,7 +42,7 @@ end
-- love.event.pump
-- @NOTE dont think can really test as internally used
love.test.event.pump = function(test)
test:skipTest('not sure can be tested as used internally')
test:skipTest('used internally')
end
+99 -5
View File
@@ -1,6 +1,101 @@
-- love.filesystem
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- File (love.filesystem.newFile)
love.test.filesystem.File = function(test)
-- setup a file to play with
local file1 = love.filesystem.openFile('data.txt', 'w')
file1:write('helloworld')
test:assertObject(file1)
file1:close()
-- test read mode
file1:open('r')
test:assertEquals('r', file1:getMode(), 'check read mode')
local contents, size = file1:read()
test:assertEquals('helloworld', contents)
test:assertEquals(10, size, 'check file read')
test:assertEquals(10, file1:getSize())
local ok, err = file1:write('hello')
test:assertNotEquals(nil, err, 'check cant write in read mode')
local iterator = file1:lines()
test:assertNotEquals(nil, iterator, 'check can read lines')
test:assertEquals('data.txt', file1:getFilename(), 'check filename matches')
file1:close()
-- test write mode
file1:open('w')
test:assertEquals('w', file1:getMode(), 'check write mode')
contents, size = file1:read()
test:assertEquals(nil, contents, 'check cant read file in write mode')
test:assertEquals('string', type(size), 'check err message shown')
ok, err = file1:write('helloworld')
test:assertEquals(true, ok, 'check file write')
test:assertEquals(nil, err, 'check no err writing')
-- test open/closing
file1:open('r')
test:assertEquals(true, file1:isOpen(), 'check file is open')
file1:close()
test:assertEquals(false, file1:isOpen(), 'check file gets closed')
file1:close()
-- test buffering and flushing
file1:open('w')
ok, err = file1:setBuffer('full', 10000)
test:assertEquals(true, ok)
test:assertEquals('full', file1:getBuffer())
file1:write('replacedcontent')
file1:flush()
file1:close()
file1:open('r')
contents, size = file1:read()
test:assertEquals('replacedcontent', contents, 'check buffered content was written')
file1:close()
-- loop through file data with seek/tell until EOF
file1:open('r')
local counter = 0
for i=1,100 do
file1:seek(i)
test:assertEquals(i, file1:tell())
if file1:isEOF() == true then
counter = i
break
end
end
test:assertEquals(counter, 15)
file1:close()
end
-- FileData (love.filesystem.newFileData)
love.test.filesystem.FileData = function(test)
-- create new obj
local fdata = love.filesystem.newFileData('helloworld', 'test.txt')
test:assertObject(fdata)
test:assertEquals('test.txt', fdata:getFilename())
test:assertEquals('txt', fdata:getExtension())
-- check properties match expected
test:assertEquals('helloworld', fdata:getString(), 'check data string')
test:assertEquals(10, fdata:getSize(), 'check data size')
-- check cloning the bytedata
local clonedfdata = fdata:clone()
test:assertObject(clonedfdata)
test:assertEquals('helloworld', clonedfdata:getString(), 'check cloned data')
test:assertEquals(10, clonedfdata:getSize(), 'check cloned size')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.filesystem.append
love.test.filesystem.append = function(test)
-- create a new file to test with
@@ -116,7 +211,7 @@ end
-- love.filesystem.getSource
-- @NOTE i dont think we can test this cos love calls it first
love.test.filesystem.getSource = function(test)
test:skipTest('not sure can be tested as used internally')
test:skipTest('used internally')
end
@@ -229,7 +324,7 @@ end
-- love.filesystem.openFile
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.filesystem.openFile = function(test)
test:assertNotNil(love.filesystem.openFile('file2.txt', 'w'))
test:assertNotNil(love.filesystem.openFile('file2.txt', 'r'))
@@ -240,7 +335,7 @@ end
-- love.filesystem.newFileData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.filesystem.newFileData = function(test)
test:assertNotNil(love.filesystem.newFileData('helloworld', 'file1'))
end
@@ -307,9 +402,8 @@ end
-- love.filesystem.setSource
-- @NOTE dont think can test this cos used internally?
love.test.filesystem.setSource = function(test)
test:skipTest('not sure can be tested as used internally')
test:skipTest('used internally')
end
+67 -7
View File
@@ -1,16 +1,76 @@
-- love.font
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- GlyphData (love.font.newGlyphData)
love.test.font.GlyphData = function(test)
-- create obj
local rasterizer = love.font.newRasterizer('resources/font.ttf')
local gdata = love.font.newGlyphData(rasterizer, 97) -- 'a'
test:assertObject(gdata)
-- check properties match expected
test:assertNotNil(gdata:getString())
test:assertEquals(128, gdata:getSize(), 'check data size')
test:assertEquals(9, gdata:getAdvance(), 'check advance')
test:assertEquals('la8', gdata:getFormat(), 'check format')
test:assertEquals(97, gdata:getGlyph(), 'check glyph number')
test:assertEquals('a', gdata:getGlyphString(), 'check glyph string')
test:assertEquals(8, gdata:getHeight(), 'check height')
test:assertEquals(8, gdata:getWidth(), 'check width')
-- check boundary
local x, y, w, h = gdata:getBoundingBox()
local dw, dh = gdata:getDimensions()
local bw, bh = gdata:getBearing()
test:assertEquals(0, x, 'check bbox x')
test:assertEquals(-3, y, 'check bbox y')
test:assertEquals(8, w, 'check bbox w')
test:assertEquals(14, h, 'check bbox h')
test:assertEquals(8, dw, 'check dim width')
test:assertEquals(8, dh, 'check dim height')
test:assertEquals(0, bw, 'check bearing w')
test:assertEquals(11, bh, 'check bearing h')
end
-- Rasterizer (love.font.newRasterizer)
love.test.font.Rasterizer = function(test)
-- create obj
local rasterizer = love.font.newRasterizer('resources/font.ttf')
test:assertObject(rasterizer)
-- check properties match
test:assertEquals(9, rasterizer:getAdvance(), 'check advance')
test:assertEquals(9, rasterizer:getAscent(), 'check ascent')
test:assertEquals(-3, rasterizer:getDescent(), 'check descent')
test:assertEquals(77, rasterizer:getGlyphCount(), 'check glyph count')
test:assertObject(rasterizer:getGlyphData('L'))
test:assertEquals(12, rasterizer:getHeight(), 'check height')
test:assertEquals(15, rasterizer:getLineHeight(), 'check line height')
test:assertEquals(true, rasterizer:hasGlyphs('L', 'O', 'V', 'E'), 'check LOVE')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.font.newBMFontRasterizer
-- @NOTE the wiki specifies diff. params to source code and trying to do
-- what source code wants gives some errors still
love.test.font.newBMFontRasterizer = function(test)
test:skipTest('wiki and source dont match, not sure expected usage')
local rasterizer = love.font.newBMFontRasterizer('resources/love.png');
test:assertObject(rasterizer)
end
-- love.font.newGlyphData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.font.newGlyphData = function(test)
local img = love.image.newImageData('resources/love.png')
local rasterizer = love.font.newImageRasterizer(img, 'ABC', 0, 1);
@@ -20,7 +80,7 @@ end
-- love.font.newImageRasterizer
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.font.newImageRasterizer = function(test)
local img = love.image.newImageData('resources/love.png')
local rasterizer = love.font.newImageRasterizer(img, 'ABC', 0, 1);
@@ -29,14 +89,14 @@ end
-- love.font.newRasterizer
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.font.newRasterizer = function(test)
test:assertObject(love.font.newRasterizer('resources/font.ttf'))
end
-- love.font.newTrueTypeRasterizer
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.font.newTrueTypeRasterizer = function(test)
test:assertObject(love.font.newTrueTypeRasterizer(12, "normal", 1))
test:assertObject(love.font.newTrueTypeRasterizer('resources/font.ttf', 8, "normal", 1))
+172 -45
View File
@@ -1,6 +1,79 @@
-- love.graphics
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Canvas (love.graphics.newCanvas)
love.test.graphics.Canvas = function(test)
test:skipTest('test class needs writing')
end
-- Font (love.graphics.newFont)
love.test.graphics.Font = function(test)
test:skipTest('test class needs writing')
end
-- Image (love.graphics.newImage)
love.test.graphics.Image = function(test)
test:skipTest('test class needs writing')
end
-- Mesh (love.graphics.newMesh)
love.test.graphics.Mesh = function(test)
test:skipTest('test class needs writing')
end
-- ParticleSystem (love.graphics.newParticleSystem)
love.test.graphics.ParticleSystem = function(test)
test:skipTest('test class needs writing')
end
-- Quad (love.graphics.newQuad)
love.test.graphics.Quad = function(test)
test:skipTest('test class needs writing')
end
-- Shader (love.graphics.newShader)
love.test.graphics.Shader = function(test)
test:skipTest('test class needs writing')
end
-- SpriteBatch (love.graphics.newSpriteBatch)
love.test.graphics.SpriteBatch = function(test)
test:skipTest('test class needs writing')
end
-- Text (love.graphics.newTextBatch)
love.test.graphics.Text = function(test)
test:skipTest('test class needs writing')
end
-- Texture (love.graphics.newTexture)
love.test.graphics.Texture = function(test)
test:skipTest('test class needs writing')
end
-- Video (love.graphics.newVideo)
love.test.graphics.Video = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------DRAWING-------------------------------------
@@ -222,7 +295,17 @@ end
-- love.graphics.flushBatch
love.test.graphics.flushBatch = function(test)
test:skipTest('not sure can be tested as used internally')
love.graphics.flushBatch()
local initial = love.graphics.getStats()['drawcalls']
local canvas = love.graphics.newCanvas(32, 32)
love.graphics.setCanvas(canvas)
love.graphics.clear(0, 0, 0, 1)
love.graphics.rectangle('fill', 0, 0, 32, 32)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setCanvas()
love.graphics.flushBatch()
local after = love.graphics.getStats()['drawcalls']
test:assertEquals(initial+1, after, 'check drawcalls increased')
end
@@ -418,7 +501,7 @@ end
-- love.graphics.newArrayImage
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newArrayImage = function(test)
test:assertObject(love.graphics.newArrayImage({
'resources/love.png', 'resources/love2.png', 'resources/love3.png'
@@ -426,7 +509,7 @@ love.test.graphics.newArrayImage = function(test)
end
-- love.graphics.newCanvas
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newCanvas = function(test)
test:assertObject(love.graphics.newCanvas(16, 16, {
type = '2d',
@@ -441,7 +524,7 @@ end
-- love.graphics.newCubeImage
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newCubeImage = function(test)
test:assertObject(love.graphics.newCubeImage('resources/cubemap.png', {
mipmaps = false,
@@ -451,7 +534,7 @@ end
-- love.graphics.newFont
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newFont = function(test)
test:assertObject(love.graphics.newFont('resources/font.ttf'))
test:assertObject(love.graphics.newFont('resources/font.ttf', 8, "normal", 1))
@@ -459,7 +542,7 @@ end
-- love.graphics.newImage
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newImage = function(test)
test:assertObject(love.graphics.newImage('resources/love.png', {
mipmaps = false,
@@ -470,21 +553,21 @@ end
-- love.graphics.newImageFont
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newImageFont = function(test)
test:assertObject(love.graphics.newImageFont('resources/love.png', 'ABCD', 1))
end
-- love.graphics.newMesh
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newMesh = function(test)
test:assertObject(love.graphics.newMesh({{1, 1, 0, 0, 1, 1, 1, 1}}, 'fan', 'dynamic'))
end
-- love.graphics.newParticleSystem
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newParticleSystem = function(test)
local imgdata = love.graphics.newImage('resources/love.png')
test:assertObject(love.graphics.newParticleSystem(imgdata, 1000))
@@ -492,7 +575,7 @@ end
-- love.graphics.newQuad
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newQuad = function(test)
local imgdata = love.graphics.newImage('resources/love.png')
test:assertObject(love.graphics.newQuad(0, 0, 16, 16, imgdata))
@@ -500,16 +583,25 @@ end
-- love.graphics.newShader
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newShader = function(test)
local pixelcode = 'vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) { vec4 texturecolor = Texel(tex, texture_coords); return texturecolor * color;}'
local vertexcode = 'vec4 position(mat4 transform_projection, vec4 vertex_position) { return transform_projection * vertex_position; }'
local pixelcode = [[
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) {
vec4 texturecolor = Texel(tex, texture_coords);
return texturecolor * color;
}
]]
local vertexcode = [[
vec4 position(mat4 transform_projection, vec4 vertex_position) {
return transform_projection * vertex_position;
}
]]
test:assertObject(love.graphics.newShader(pixelcode, vertexcode))
end
-- love.graphics.newSpriteBatch
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newSpriteBatch = function(test)
local imgdata = love.graphics.newImage('resources/love.png')
test:assertObject(love.graphics.newSpriteBatch(imgdata, 1000))
@@ -517,7 +609,7 @@ end
-- love.graphics.newText
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @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')
test:assertObject(love.graphics.newTextBatch(font, 'helloworld'))
@@ -525,7 +617,7 @@ end
-- love.graphics.newVideo
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newVideo = function(test)
test:assertObject(love.graphics.newVideo('resources/sample.ogv', {
audio = false,
@@ -535,7 +627,7 @@ end
-- love.graphics.newVolumeImage
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.graphics.newVolumeImage = function(test)
test:assertObject(love.graphics.newVolumeImage({
'resources/love.png', 'resources/love2.png', 'resources/love3.png'
@@ -548,8 +640,17 @@ end
-- love.graphics.validateShader
love.test.graphics.validateShader = function(test)
local pixelcode = 'vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) { vec4 texturecolor = Texel(tex, texture_coords); return texturecolor * color;}'
local vertexcode = 'vec4 position(mat4 transform_projection, vec4 vertex_position) { return transform_projection * vertex_position; }'
local pixelcode = [[
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) {
vec4 texturecolor = Texel(tex, texture_coords);
return texturecolor * color;
}
]]
local vertexcode = [[
vec4 position(mat4 transform_projection, vec4 vertex_position) {
return transform_projection * vertex_position;
}
]]
-- check made up code first
local status, _ = love.graphics.validateShader(true, 'nothing here', 'or here')
test:assertEquals(false, status, 'check invalid shader code')
@@ -829,25 +930,37 @@ end
-- love.graphics.isActive
love.test.graphics.isActive = function(test)
test:assertEquals(true, love.graphics.isActive(), 'check graphics is active') -- i mean if you got this far
local name, version, vendor, device = love.graphics.getRendererInfo()
if string.find(name, 'Vulkan') ~= nil then
test:skipTest('love.graphics.isActive() crashes on Vulkan')
else
test:assertEquals(true, love.graphics.isActive(), 'check graphics is active') -- i mean if you got this far
end
end
-- love.graphics.isGammaCorrect
love.test.graphics.isGammaCorrect = function(test)
-- we know the config so know this is false
test:assertEquals(false, love.graphics.isGammaCorrect(), 'check gamma correct false')
print('gammaCorrect #1')
test:assertNotNil(love.graphics.isGammaCorrect())
print('gammaCorrect #2')
end
-- love.graphics.isWireframe
love.test.graphics.isWireframe = function(test)
-- check off by default
test:assertEquals(false, love.graphics.isWireframe(), 'check no wireframe by default')
-- check on when enabled
love.graphics.setWireframe(true)
test:assertEquals(true, love.graphics.isWireframe(), 'check wireframe is set')
love.graphics.setWireframe(false) -- reset
local name, version, vendor, device = love.graphics.getRendererInfo()
if string.match(name, 'OpenGL ES') then
test:skipTest('Wireframe not supported on OpenGL ES')
else
-- check off by default
test:assertEquals(false, love.graphics.isWireframe(), 'check no wireframe by default')
-- check on when enabled
love.graphics.setWireframe(true)
test:assertEquals(true, love.graphics.isWireframe(), 'check wireframe is set')
love.graphics.setWireframe(false) -- reset
end
end
@@ -1193,8 +1306,17 @@ end
-- love.graphics.setShader
love.test.graphics.setShader = function(test)
-- make a shader that will only ever draw yellow
local pixelcode = 'vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) { vec4 texturecolor = Texel(tex, texture_coords); return vec4(1.0,1.0,0.0,1.0);}'
local vertexcode = 'vec4 position(mat4 transform_projection, vec4 vertex_position) { return transform_projection * vertex_position; }'
local pixelcode = [[
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) {
vec4 texturecolor = Texel(tex, texture_coords);
return vec4(1.0,1.0,0.0,1.0);
}
]]
local vertexcode = [[
vec4 position(mat4 transform_projection, vec4 vertex_position) {
return transform_projection * vertex_position;
}
]]
local shader = love.graphics.newShader(pixelcode, vertexcode)
local canvas = love.graphics.newCanvas(16, 16)
love.graphics.setCanvas(canvas)
@@ -1238,22 +1360,27 @@ end
-- love.graphics.setWireframe
love.test.graphics.setWireframe = function(test)
-- check wireframe outlines
love.graphics.setWireframe(true)
local canvas = love.graphics.newCanvas(16, 16)
love.graphics.setCanvas(canvas)
love.graphics.clear(0, 0, 0, 1)
love.graphics.setColor(1, 1, 0, 1)
love.graphics.rectangle('fill', 2, 2, 13, 13)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setWireframe(false)
love.graphics.setCanvas()
local imgdata = love.graphics.readbackTexture(canvas, {16, 0, 0, 0, 16, 16})
test:assertPixels(imgdata, {
yellow = {{1,14},{14,1},{14,14},{2,2},{13,13}},
black = {{2,13},{13,2}}
}, 'set wireframe')
test:exportImg(imgdata)
local name, version, vendor, device = love.graphics.getRendererInfo()
if string.match(name, 'OpenGL ES') then
test:skipTest('Wireframe not supported on OpenGL ES')
else
-- check wireframe outlines
love.graphics.setWireframe(true)
local canvas = love.graphics.newCanvas(16, 16)
love.graphics.setCanvas(canvas)
love.graphics.clear(0, 0, 0, 1)
love.graphics.setColor(1, 1, 0, 1)
love.graphics.rectangle('fill', 2, 2, 13, 13)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setWireframe(false)
love.graphics.setCanvas()
local imgdata = love.graphics.readbackTexture(canvas, {16, 0, 0, 0, 16, 16})
test:assertPixels(imgdata, {
yellow = {{1,14},{14,1},{14,14},{2,2},{13,13}},
black = {{2,13},{13,2}}
}, 'set wireframe')
test:exportImg(imgdata)
end
end
+77 -2
View File
@@ -1,6 +1,81 @@
-- love.image
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CompressedImageData (love.image.newCompressedImageData)
love.test.image.CompressedImageData = function(test)
-- create obj
local idata = love.image.newCompressedData('resources/love.dxt1')
test:assertObject(idata)
-- check data properties
test:assertNotEquals(nil, idata:getString(), 'check data string')
test:assertEquals(2744, idata:getSize(), 'check data size')
-- check img data properties
local iw, ih = idata:getDimensions()
test:assertEquals(64, iw, 'check image dimension w')
test:assertEquals(64, ih, 'check image dimension h')
test:assertEquals('DXT1', idata:getFormat(), 'check image format')
test:assertEquals(64, idata:getWidth(), 'check image direct w')
test:assertEquals(64, idata:getHeight(), 'check image direct h')
test:assertEquals(7, idata:getMipmapCount(), 'check mipmap count')
end
-- ImageData (love.image.newImageData)
love.test.image.ImageData = function(test)
-- create obj
local idata = love.image.newImageData('resources/love.png')
test:assertObject(idata)
-- check data properties
test:assertNotEquals(nil, idata:getString(), 'check data string')
test:assertEquals(16384, idata:getSize(), 'check data size')
-- check img data properties
local iw, ih = idata:getDimensions()
test:assertEquals(64, iw, 'check image dimension w')
test:assertEquals(64, ih, 'check image dimension h')
test:assertEquals('rgba8', idata:getFormat(), 'check image format')
test:assertEquals(64, idata:getWidth(), 'check image direct w')
test:assertEquals(64, idata:getHeight(), 'check image direct h')
-- manipulate image data so white heart is black
local mapdata = function(x, y, r, g, b, a)
if r == 1 and g == 1 and b == 1 then
r = 0; g = 0; b = 0
end
return r, g, b, a
end
idata:mapPixel(mapdata, 0, 0, 64, 64)
local r1, g1, b1 = idata:getPixel(25, 25)
test:assertEquals(0, r1+g1+b1, 'check mapped black')
-- map some other data into the idata
local idata2 = love.image.newImageData('resources/loveinv.png')
idata:paste(idata2, 0, 0, 0, 0)
r1, g1, b1 = idata:getPixel(25, 25)
test:assertEquals(3, r1+g1+b1, 'check back to white')
-- set pixels directly
idata:setPixel(25, 25, 1, 0, 0, 1)
r1, g1, b1 = idata:getPixel(25, 25)
test:assertEquals(1, r1+g1+b1, 'check set to red')
-- check encoding to an image
idata:encode('png', 'test-encode.png')
local read = love.filesystem.openFile('test-encode.png', 'r')
test:assertNotNil(read)
love.filesystem.remove('test-encode.png')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.image.isCompressed
-- @NOTE really we need to test each of the files listed here:
-- https://love2d.org/wiki/CompressedImageFormat
@@ -12,14 +87,14 @@ end
-- love.image.newCompressedData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.image.newCompressedData = function(test)
test:assertObject(love.image.newCompressedData('resources/love.dxt1'))
end
-- love.image.newImageData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.image.newImageData = function(test)
test:assertObject(love.image.newImageData('resources/love.png'))
test:assertObject(love.image.newImageData(16, 16, 'rgba8', nil))
+153 -3
View File
@@ -1,6 +1,156 @@
-- love.math
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- BezierCurve (love.math.newBezierCurve)
love.test.math.BezierCurve = function(test)
-- create obj
local curve = love.math.newBezierCurve(1, 1, 2, 2, 3, 1)
local px, py = curve:getControlPoint(2)
test:assertObject(curve)
-- check initial properties
test:assertCoords({2, 2}, {px, py}, 'check point x/y')
test:assertEquals(3, curve:getControlPointCount(), 'check 3 points')
test:assertEquals(2, curve:getDegree(), 'check degree is points-1')
-- check some values on the curve
test:assertEquals(1, curve:evaluate(0), 'check curve evaluation 0')
test:assertEquals(120, math.floor(curve:evaluate(0.1)*100), 'check curve evaluation 0.1')
test:assertEquals(140, math.floor(curve:evaluate(0.2)*100), 'check curve evaluation 0.2')
test:assertEquals(200, math.floor(curve:evaluate(0.5)*100), 'check curve evaluation 0.5')
test:assertEquals(3, curve:evaluate(1), 'check curve evaluation 1')
-- check derivative
local deriv = curve:getDerivative()
test:assertObject(deriv)
test:assertEquals(2, deriv:getControlPointCount(), 'check deriv points')
test:assertEquals(200, math.floor(deriv:evaluate(0.1)*100), 'check deriv evaluation 0.1')
-- check segment
local segment = curve:getSegment(0, 0.5)
test:assertObject(segment)
test:assertEquals(3, segment:getControlPointCount(), 'check segment points')
test:assertEquals(109, math.floor(segment:evaluate(0.1)*100), 'check segment evaluation 0.1')
-- mess with control points
curve:removeControlPoint(2)
curve:insertControlPoint(4, 1, -1)
curve:insertControlPoint(5, 3, -1)
curve:insertControlPoint(6, 2, -1)
curve:setControlPoint(2, 3, 2)
test:assertEquals(5, curve:getControlPointCount(), 'check 3 points still')
local px1, py1 = curve:getControlPoint(1)
local px2, py2 = curve:getControlPoint(3)
local px3, py3 = curve:getControlPoint(5)
test:assertCoords({1, 1}, {px1, py1}, 'check modified point 1')
test:assertCoords({5, 3}, {px2, py2}, 'check modified point 1')
test:assertCoords({3, 1}, {px3, py3}, 'check modified point 1')
-- check render lists
local coords1 = curve:render(5)
local coords2 = curve:renderSegment(0, 0.1, 5)
test:assertEquals(196, #coords1, 'check coords')
test:assertEquals(20, #coords2, 'check segment coords')
-- check translation values
px, py = curve:getControlPoint(2)
test:assertCoords({3, 2}, {px, py}, 'check pretransform x/y')
curve:rotate(90 * (math.pi/180), 0, 0)
px, py = curve:getControlPoint(2)
test:assertCoords({-2, 3}, {px, py}, 'check rotated x/y')
curve:scale(2, 0, 0)
px, py = curve:getControlPoint(2)
test:assertCoords({-4, 6}, {px, py}, 'check scaled x/y')
curve:translate(5, -5)
px, py = curve:getControlPoint(2)
test:assertCoords({1, 1}, {px, py}, 'check translated x/y')
end
-- RandomGenerator (love.math.RandomGenerator)
-- @NOTE as this checks random numbers the chances this fails is very unlikely, but not 0...
-- if you've managed to proc it congrats! your prize is to rerun the testsuite again
love.test.math.RandomGenerator = function(test)
-- create object
local rng1 = love.math.newRandomGenerator(3418323524, 20529293)
test:assertObject(rng1)
-- check set properties
local low, high = rng1:getSeed()
test:assertEquals(3418323524, low, 'check seed low')
test:assertEquals(20529293, high, 'check seed high')
-- check states
local rng2 = love.math.newRandomGenerator(1448323524, 10329293)
test:assertNotEquals(rng1:random(), rng2:random(), 'check not matching states')
test:assertNotEquals(rng1:randomNormal(), rng2:randomNormal(), 'check not matching states')
-- check setting state works
rng2:setState(rng1:getState())
test:assertEquals(rng1:random(), rng2:random(), 'check now matching')
-- check overwriting seed works, should change output
rng1:setSeed(os.time())
test:assertNotEquals(rng1:random(), rng2:random(), 'check not matching states')
test:assertNotEquals(rng1:randomNormal(), rng2:randomNormal(), 'check not matching states')
end
-- Transform (love.math.Transform)
love.test.math.Transform = function(test)
-- create obj
local transform = love.math.newTransform(0, 0, 0, 1, 1, 0, 0, 0, 0)
test:assertObject(transform)
-- set some values and check the matrix and transformPoint values
transform:translate(10, 8)
transform:scale(2, 3)
transform:rotate(90*(math.pi/180))
transform:shear(1, 2)
local px, py = transform:transformPoint(1, 1)
test:assertCoords({4, 14}, {px, py}, 'check transformation methods')
transform:reset()
px, py = transform:transformPoint(1, 1)
test:assertCoords({1, 1}, {px, py}, 'check reset')
-- apply a transform to another transform
local transform2 = love.math.newTransform()
transform2:translate(5, 3)
transform:apply(transform2)
px, py = transform:transformPoint(1, 1)
test:assertCoords({6, 4}, {px, py}, 'check apply other transform')
-- check cloning a transform
local transform3 = transform:clone()
px, py = transform3:transformPoint(1, 1)
test:assertCoords({6, 4}, {px, py}, 'check clone transform')
-- check inverse and inverseTransform
transform:reset()
transform:translate(-14, 6)
local ipx, ipy = transform:inverseTransformPoint(0, 0)
transform:inverse()
px, py = transform:transformPoint(0, 0)
test:assertCoords({-px, -py}, {ipx, ipy}, 'check inverse points transform')
-- check matrix manipulation
transform:setTransformation(0, 0, 0, 1, 1, 0, 0, 0, 0)
transform:translate(4, 4)
local m1, m2, m3, m4, m5, m6, m7, m8,
m9, m10, m11, m12, m13, m14, m15, m16 = transform:getMatrix()
test:assertEquals(4, m4, 'check translate matrix x')
test:assertEquals(4, m8, 'check translate matrix y')
transform:setMatrix(m1, m2, m3, 3, m5, m6, m7, 1, m9, m10, m11, m12, m13, m14, m15, m16)
px, py = transform:transformPoint(1, 1)
test:assertCoords({4, 2}, {px, py}, 'check set matrix')
-- check affine vs non affine
transform:reset()
test:assertEquals(true, transform:isAffine2DTransform(), 'check affine 1')
transform:translate(4, 3)
test:assertEquals(true, transform:isAffine2DTransform(), 'check affine 2')
transform:setMatrix(1, 3, 4, 5.5, 1, 4.5, 2, 1, 3.4, 5.1, 4.1, 13, 1, 1, 2, 3)
test:assertEquals(false, transform:isAffine2DTransform(), 'check not affine')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.math.colorFromBytes
love.test.math.colorFromBytes = function(test)
-- check random value
@@ -98,21 +248,21 @@ end
-- love.math.newBezierCurve
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.math.newBezierCurve = function(test)
test:assertObject(love.math.newBezierCurve({0, 0, 0, 1, 1, 1, 2, 1}))
end
-- love.math.newRandomGenerator
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.math.newRandomGenerator = function(test)
test:assertObject(love.math.newRandomGenerator())
end
-- love.math.newTransform
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.math.newTransform = function(test)
test:assertObject(love.math.newTransform())
end
-411
View File
@@ -1,411 +0,0 @@
-- objects put in their own test methods to test all attributes and class methods
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------AUDIO---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- RecordingDevice (love.audio.getRecordingDevices)
love.test.objects.RecordingDevice = function(test)
test:skipTest('test class needs writing')
end
-- Source (love.audio.newSource)
love.test.objects.Source = function(test)
test:skipTest('test class needs writing')
-- local source1 = love.audio.newSource('resources/click.ogg', 'static')
--source1:clone()
--source1:getChannelCount()
--source1:getDuration()
--source1:isRelative()
--source1:queue()
--source1:getFreeBufferCount()
--source1:getType()
--source1:isPlaying()
--source1:play()
--source1:pause()
--source1:stop()
--source1:seek()
--source1:tell()
--source1:isLooping()
--source1:setLooping()
--source1:setAirAbsorption()
--source1:getAirAbsorption()
--source1:setAttenuationDistances()
--source1:getAttenuationDistances()
--source1:setCone()
--source1:getCone()
--source1:setDirection()
--source1:getDirection()
--source1:setEffect()
--source1:getEffect()
--source1:getActiveEffects()
--source1:setFilter()
--source1:getFilter()
--source1:setPitch()
--source1:getPitch()
--source1:setPosition()
--source1:getPosition()
--source1:setRelative()
--source1:setRolloff()
--source1:getRolloff()
--source1:setVelocity()
--source1:getVelocity()
--source1:setVolume()
--source1:getVolume()
--source1:setVolumeLimits()
--source1:getVolumeLimits()
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------DATA----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- ByteData (love.data.newByteData)
love.test.objects.ByteData = function(test)
test:skipTest('test class needs writing')
end
-- CompressedData (love.data.compress)
love.test.objects.CompressedData = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---------------------------------FILESYSTEM-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- File (love.filesystem.newFile)
love.test.objects.File = function(test)
-- setup a file to play with
local file1 = love.filesystem.openFile('data.txt', 'w')
file1:write('helloworld')
test:assertObject(file1)
file1:close()
-- test read mode
file1:open('r')
test:assertEquals('r', file1:getMode(), 'check read mode')
local contents, size = file1:read()
test:assertEquals('helloworld', contents)
test:assertEquals(10, size, 'check file read')
test:assertEquals(10, file1:getSize())
local ok, err = file1:write('hello')
test:assertNotEquals(nil, err, 'check cant write in read mode')
local iterator = file1:lines()
test:assertNotEquals(nil, iterator, 'check can read lines')
test:assertEquals('data.txt', file1:getFilename(), 'check filename matches')
file1:close()
-- test write mode
file1:open('w')
test:assertEquals('w', file1:getMode(), 'check write mode')
contents, size = file1:read()
test:assertEquals(nil, contents, 'check cant read file in write mode')
test:assertEquals('string', type(size), 'check err message shown')
ok, err = file1:write('helloworld')
test:assertEquals(true, ok, 'check file write')
test:assertEquals(nil, err, 'check no err writing')
-- test open/closing
file1:open('r')
test:assertEquals(true, file1:isOpen(), 'check file is open')
file1:close()
test:assertEquals(false, file1:isOpen(), 'check file gets closed')
file1:close()
-- test buffering
-- @NOTE think I'm just not understanding how this is supposed to work?
-- I thought if buffering is enabled then nothing should get written until
-- buffer overflows?
-- file1:open('a')
-- ok, err = file1:setBuffer('full', 10000)
-- test:assertEquals(true, ok)
-- test:assertEquals('full', file1:getBuffer())
-- file1:write('morecontent')
-- file1:close()
-- file1:open('r')
-- contents, size = file1:read()
-- test:assertEquals('helloworld', contents, 'check buffered content wasnt written')
-- file1:close()
-- @NOTE :close() commits buffer content so need to check before not after
-- test buffering and flushing
file1:open('w')
ok, err = file1:setBuffer('full', 10000)
test:assertEquals(true, ok)
test:assertEquals('full', file1:getBuffer())
file1:write('replacedcontent')
file1:flush()
file1:close()
file1:open('r')
contents, size = file1:read()
test:assertEquals('replacedcontent', contents, 'check buffered content was written')
file1:close()
-- loop through file data with seek/tell until EOF
file1:open('r')
local counter = 0
for i=1,100 do
file1:seek(i)
test:assertEquals(i, file1:tell())
if file1:isEOF() == true then
counter = i
break
end
end
test:assertEquals(counter, 15)
file1:close()
end
-- FileData (love.filesystem.newFileData)
love.test.objects.FileData = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------FONT----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- GlyphData (love.font.newGlyphData)
love.test.objects.GlyphData = function(test)
test:skipTest('test class needs writing')
end
-- Rasterizer (love.font.newRasterizer)
love.test.objects.Rasterizer = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---------------------------------GRAPHICS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Canvas (love.graphics.newCanvas)
love.test.objects.Canvas = function(test)
test:skipTest('test class needs writing')
end
-- Font (love.graphics.newFont)
love.test.objects.Font = function(test)
test:skipTest('test class needs writing')
end
-- Image (love.graphics.newImage)
love.test.objects.Image = function(test)
test:skipTest('test class needs writing')
end
-- Mesh (love.graphics.newMesh)
love.test.objects.Mesh = function(test)
test:skipTest('test class needs writing')
end
-- ParticleSystem (love.graphics.newParticleSystem)
love.test.objects.ParticleSystem = function(test)
test:skipTest('test class needs writing')
end
-- Quad (love.graphics.newQuad)
love.test.objects.Quad = function(test)
test:skipTest('test class needs writing')
end
-- Shader (love.graphics.newShader)
love.test.objects.Shader = function(test)
test:skipTest('test class needs writing')
end
-- SpriteBatch (love.graphics.newSpriteBatch)
love.test.objects.SpriteBatch = function(test)
test:skipTest('test class needs writing')
end
-- Text (love.graphics.newTextBatch)
love.test.objects.Text = function(test)
test:skipTest('test class needs writing')
end
-- Texture (love.graphics.newTexture)
love.test.objects.Texture = function(test)
test:skipTest('test class needs writing')
end
-- Video (love.graphics.newVideo)
love.test.objects.Video = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------IMAGE----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CompressedImageData (love.image.newCompressedImageData)
love.test.objects.CompressedImageData = function(test)
test:skipTest('test class needs writing')
end
-- ImageData (love.image.newImageData)
love.test.objects.ImageData = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------MATH----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- BezierCurve (love.math.newBezierCurve)
love.test.objects.BezierCurve = function(test)
test:skipTest('test class needs writing')
end
-- RandomGenerator (love.math.RandomGenerator)
love.test.objects.RandomGenerator = function(test)
test:skipTest('test class needs writing')
end
-- Transform (love.math.Transform)
love.test.objects.Transform = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------PHYSICS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Body (love.physics.newBody)
love.test.objects.Body = function(test)
test:skipTest('test class needs writing')
end
-- Contact (love.physics.World:getContacts)
love.test.objects.Contact = function(test)
test:skipTest('test class needs writing')
end
-- Fixture (love.physics.newFixture)
love.test.objects.Fixture = function(test)
test:skipTest('test class needs writing')
end
-- Joint (love.physics.newDistanceJoint)
love.test.objects.Joint = function(test)
test:skipTest('test class needs writing')
end
-- Shape (love.physics.newCircleShape)
love.test.objects.Shape = function(test)
test:skipTest('test class needs writing')
end
-- World (love.physics.newWorld)
love.test.objects.World = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------SOUND----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Decoder (love.sound.newDecoder)
love.test.objects.Decoder = function(test)
test:skipTest('test class needs writing')
end
-- SoundData (love.sound.newSoundData)
love.test.objects.SoundData = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------THREAD----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Channel (love.thread.newChannel)
love.test.objects.Channel = function(test)
test:skipTest('test class needs writing')
end
-- Thread (love.thread.newThread)
love.test.objects.Thread = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------VIDEO----------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- VideoStream (love.thread.newVideoStream)
love.test.objects.VideoStream = function(test)
test:skipTest('test class needs writing')
end
+69 -19
View File
@@ -1,6 +1,56 @@
-- love.physics
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------OBJECTS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Body (love.physics.newBody)
love.test.physics.Body = function(test)
test:skipTest('test class needs writing')
end
-- Contact (love.physics.World:getContacts)
love.test.physics.Contact = function(test)
test:skipTest('test class needs writing')
end
-- Fixture (love.physics.newFixture)
love.test.physics.Fixture = function(test)
test:skipTest('test class needs writing')
end
-- Joint (love.physics.newDistanceJoint)
love.test.physics.Joint = function(test)
test:skipTest('test class needs writing')
end
-- Shape (love.physics.newCircleShape)
love.test.physics.Shape = function(test)
test:skipTest('test class needs writing')
end
-- World (love.physics.newWorld)
love.test.physics.World = function(test)
test:skipTest('test class needs writing')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.physics.getDistance
love.test.physics.getDistance = function(test)
-- setup two fixtues to check
@@ -24,7 +74,7 @@ end
-- love.physics.newBody
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newBody = function(test)
local world = love.physics.newWorld(1, 1, true)
local body = love.physics.newBody(world, 10, 10, 'static')
@@ -33,21 +83,21 @@ end
-- love.physics.newChainShape
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newChainShape = function(test)
test:assertObject(love.physics.newChainShape(true, 0, 0, 1, 0, 1, 1, 0, 1))
end
-- love.physics.newCircleShape
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newCircleShape = function(test)
test:assertObject(love.physics.newCircleShape(10))
end
-- love.physics.newDistanceJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newDistanceJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -58,7 +108,7 @@ end
-- love.physics.newEdgeShape
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newEdgeShape = function(test)
local obj = love.physics.newEdgeShape(0, 0, 10, 10)
test:assertObject(obj)
@@ -66,7 +116,7 @@ end
-- love.physics.newFixture
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newFixture = function(test)
local world = love.physics.newWorld(1, 1, true)
local body = love.physics.newBody(world, 10, 10, 'static')
@@ -77,7 +127,7 @@ end
-- love.physics.newFrictionJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newFrictionJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -88,7 +138,7 @@ end
-- love.physics.newGearJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newGearJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'dynamic')
@@ -103,7 +153,7 @@ end
-- love.physics.newMotorJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newMotorJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -114,7 +164,7 @@ end
-- love.physics.newMouseJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newMouseJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body = love.physics.newBody(world, 10, 10, 'static')
@@ -124,7 +174,7 @@ end
-- love.physics.newPolygonShape
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newPolygonShape = function(test)
local obj = love.physics.newPolygonShape({0, 0, 2, 3, 2, 1, 3, 1, 5, 1})
test:assertObject(obj)
@@ -132,7 +182,7 @@ end
-- love.physics.newPrismaticJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newPrismaticJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -143,7 +193,7 @@ end
-- love.physics.newPulleyJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newPulleyJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -154,7 +204,7 @@ end
-- love.physics.newRectangleShape
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newRectangleShape = function(test)
local shape1 = love.physics.newRectangleShape(10, 20)
local shape2 = love.physics.newRectangleShape(10, 10, 40, 30, 10)
@@ -164,7 +214,7 @@ end
-- love.physics.newRevoluteJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newRevoluteJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -175,7 +225,7 @@ end
-- love.physics.newRopeJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newRopeJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -186,7 +236,7 @@ end
-- love.physics.newWeldJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newWeldJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -197,7 +247,7 @@ end
-- love.physics.newWheelJoint
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newWheelJoint = function(test)
local world = love.physics.newWorld(1, 1, true)
local body1 = love.physics.newBody(world, 10, 10, 'static')
@@ -208,7 +258,7 @@ end
-- love.physics.newWorld
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.physics.newWorld = function(test)
local world = love.physics.newWorld(1, 1, true)
test:assertObject(world)
+68 -2
View File
@@ -1,15 +1,81 @@
-- love.sound
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------OBJECTS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Decoder (love.sound.newDecoder)
love.test.sound.Decoder = function(test)
-- create obj
local decoder = love.sound.newDecoder('resources/click.ogg')
test:assertObject(decoder)
-- check decoder props
test:assertMatch({8, 16}, decoder:getBitDepth(), 'check bit depth')
test:assertMatch({1, 2}, decoder:getChannelCount(), 'check channel count')
test:assertEquals(66, math.floor(decoder:getDuration()*1000), 'check duration')
test:assertEquals(44100, decoder:getSampleRate(), 'check sample rate')
-- check makes sound data (test in method below)
test:assertObject(decoder:decode())
-- check cloning sound
local clone = decoder:clone()
test:assertMatch({8, 16}, clone:getBitDepth(), 'check cloned bit depth')
test:assertMatch({1, 2}, clone:getChannelCount(), 'check cloned channel count')
test:assertEquals(66, math.floor(clone:getDuration()*1000), 'check cloned duration')
test:assertEquals(44100, clone:getSampleRate(), 'check cloned sample rate')
end
-- SoundData (love.sound.newSoundData)
love.test.sound.SoundData = function(test)
-- create obj
local sdata = love.sound.newSoundData('resources/click.ogg')
test:assertObject(sdata)
-- check data props
test:assertEquals(11708, sdata:getSize(), 'check size')
test:assertNotNil(sdata:getString())
test:assertMatch({8, 16}, sdata:getBitDepth(), 'check bit depth')
test:assertMatch({1, 2}, sdata:getChannelCount(), 'check channel count')
test:assertEquals(66, math.floor(sdata:getDuration()*1000), 'check duration')
test:assertEquals(44100, sdata:getSampleRate(), 'check sample rate')
test:assertEquals(2927, sdata:getSampleCount(), 'check sample count')
-- check cloning
local clone = sdata:clone()
test:assertEquals(11708, clone:getSize(), 'check clone size')
test:assertNotNil(clone:getString())
test:assertMatch({8, 16}, clone:getBitDepth(), 'check clone bit depth')
test:assertMatch({1, 2}, clone:getChannelCount(), 'check clone channel count')
test:assertEquals(66, math.floor(clone:getDuration()*1000), 'check clone duration')
test:assertEquals(44100, clone:getSampleRate(), 'check clone sample rate')
test:assertEquals(2927, clone:getSampleCount(), 'check clone sample count')
-- check sample setting
test:assertEquals(-22, math.floor(sdata:getSample(0.001)*100000), 'check sample 1')
test:assertEquals(-22, math.floor(sdata:getSample(0.005)*100000), 'check sample 1')
sdata:setSample(0.002, 1)
test:assertEquals(1, sdata:getSample(0.002), 'check setting sample manually')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------------METHODS-------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.sound.newDecoder
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.sound.newDecoder = function(test)
test:assertObject(love.sound.newDecoder('resources/click.ogg'))
end
-- love.sound.newSoundData
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.sound.newSoundData = function(test)
test:assertObject(love.sound.newSoundData('resources/click.ogg'))
test:assertObject(love.sound.newSoundData(math.floor((1/32)*44100), 44100, 16, 1))
+7
View File
@@ -1,6 +1,13 @@
-- love.system
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------METHODS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.system.getClipboardText
love.test.system.getClipboardText = function(test)
-- ignore if not using window
+105 -3
View File
@@ -1,22 +1,124 @@
-- love.thread
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------OBJECTS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Channel (love.thread.newChannel)
love.test.thread.Channel = function(test)
-- create channel
local channel = love.thread.getChannel('test')
test:assertObject(channel)
-- setup thread to use
local threadcode1 = [[
require("love.timer")
love.timer.sleep(0.1)
love.thread.getChannel('test'):push('hello world')
love.timer.sleep(0.1)
love.thread.getChannel('test'):push('me again')
]]
local thread1 = love.thread.newThread(threadcode1)
thread1:start()
-- check message sent from thread to channel
local msg1 = channel:demand()
test:assertEquals('hello world', msg1, 'check 1st message was sent')
thread1:wait()
test:assertEquals(1, channel:getCount(), 'check still another message')
test:assertEquals('me again', channel:peek(), 'check 2nd message pending')
local msg2 = channel:pop()
test:assertEquals('me again', msg2, 'check 2nd message was sent')
channel:clear()
-- setup another thread for some ping pong
local threadcode2 = [[
local function setChannel(channel, value)
channel:clear()
return channel:push(value)
end
local channel = love.thread.getChannel('test')
local waiting = true
local sent = nil
while waiting == true do
if sent == nil then
sent = channel:performAtomic(setChannel, 'ping')
end
if channel:hasRead(sent) then
local msg = channel:demand()
if msg == 'pong' then
channel:push(msg)
waiting = false
end
end
end
]]
-- first we run a thread that will send 1 ping
local thread2 = love.thread.newThread(threadcode2)
thread2:start()
-- we wait for that ping to be sent and then send a pong back
local msg3 = channel:demand()
test:assertEquals('ping', msg3, 'check message recieved 1')
-- thread should be waiting for us, and checking is the ping was read
channel:supply('pong', 1)
-- if it was then it should send back our pong and thread should die
thread2:wait()
local msg4 = channel:pop()
test:assertEquals('pong', msg4, 'check message recieved 2')
test:assertEquals(0, channel:getCount())
end
-- Thread (love.thread.newThread)
love.test.thread.Thread = function(test)
-- create thread
local threadcode = [[
local b = 0
for a=1,100000 do
b = b + a
end
]]
local thread = love.thread.newThread(threadcode)
test:assertObject(thread)
-- check thread runs
thread:start()
test:assertEquals(true, thread:isRunning(), 'check started')
thread:wait()
test:assertEquals(false, thread:isRunning(), 'check finished')
test:assertEquals(nil, thread:getError(), 'check no errors')
-- check an invalid thread
local badthreadcode = 'local b = 0\nreturn b + "string" .. 10'
local badthread = love.thread.newThread(badthreadcode)
badthread:start()
badthread:wait()
test:assertNotNil(badthread:getError())
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------METHODS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.thread.getChannel
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.thread.getChannel = function(test)
test:assertObject(love.thread.getChannel('test'))
end
-- love.thread.newChannel
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.thread.newChannel = function(test)
test:assertObject(love.thread.newChannel())
end
-- love.thread.newThread
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.thread.newThread = function(test)
test:assertObject(love.thread.newThread('classes/TestSuite.lua'))
end
+7
View File
@@ -1,6 +1,13 @@
-- love.timer
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------METHODS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.timer.getAverageDelta
-- @NOTE not sure if you could reliably get a specific delta?
love.test.timer.getAverageDelta = function(test)
+35 -1
View File
@@ -1,8 +1,42 @@
-- love.video
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------OBJECTS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- VideoStream (love.thread.newVideoStream)
love.test.video.VideoStream = function(test)
-- create obj
local video = love.video.newVideoStream('resources/sample.ogv')
test:assertObject(video)
-- check def properties
test:assertEquals('resources/sample.ogv', video:getFilename(), 'check filename')
test:assertEquals(false, video:isPlaying(), 'check not playing by def')
-- check playing and pausing
video:play()
test:assertEquals(true, video:isPlaying(), 'check now playing')
video:seek(0.3)
test:assertEquals(0.3, video:tell(), 'check seek/tell')
video:rewind()
test:assertEquals(0, video:tell(), 'check rewind')
video:pause()
test:assertEquals(false, video:isPlaying(), 'check paused')
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------METHODS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.video.newVideoStream
-- @NOTE this is just basic nil checking, full obj test are in objects.lua
-- @NOTE this is just basic nil checking, objs have their own test method
love.test.video.newVideoStream = function(test)
test:assertObject(love.video.newVideoStream('resources/sample.ogv'))
end
+54 -32
View File
@@ -1,6 +1,13 @@
-- love.window
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------METHODS---------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- love.window.close
love.test.window.close = function(test)
-- closing window should cause graphics to not be active
@@ -130,12 +137,6 @@ end
-- love.window.getVSync
love.test.window.getVSync = function(test)
test:assertNotNil(love.window.getVSync())
-- check turning off
love.window.setVSync(0)
test:assertEquals(0, love.window.getVSync(), 'check vsync off')
-- check turning on
love.window.setVSync(1)
test:assertEquals(1, love.window.getVSync(), 'check vsync on')
end
@@ -168,6 +169,7 @@ end
-- love.window.isMaximized
love.test.window.isMaximized = function(test)
if test:isDelayed() == false then
test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
love.window.maximize()
test:setDelay(10)
else
@@ -180,12 +182,17 @@ end
-- love.window.isMinimized
love.test.window.isMinimized = function(test)
-- check not minimized to start
test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
-- try to minimize
love.window.minimize()
test:assertEquals(true, love.window.isMinimized(), 'check window minimized')
love.window.restore()
if test:isDelayed() == false then
-- check not minimized to start
test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
-- try to minimize
love.window.minimize()
test:setDelay(10)
else
-- on linux minimize won't get recognized immediately, so wait a few frames
test:assertEquals(true, love.window.isMinimized(), 'check window minimized')
love.window.restore()
end
end
@@ -214,6 +221,7 @@ end
-- love.window.maximize
love.test.window.maximize = function(test)
if test:isDelayed() == false then
test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
-- check maximizing is set
love.window.maximize()
test:setDelay(10)
@@ -227,10 +235,16 @@ end
-- love.window.minimize
love.test.window.minimize = function(test)
-- check minimizing is set
love.window.minimize()
test:assertEquals(true, love.window.isMinimized(), 'check window minimized')
love.window.restore()
if test:isDelayed() == false then
test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
-- check minimizing is set
love.window.minimize()
test:setDelay(10)
else
-- on linux we need to wait a few frames
test:assertEquals(true, love.window.isMinimized(), 'check window maximized')
love.window.restore()
end
end
@@ -242,12 +256,20 @@ end
-- love.window.restore
love.test.window.restore = function(test)
-- check minimized to start
love.window.minimize()
test:assertEquals(true, love.window.isMinimized(), 'check window minimized')
-- check restoring the state of the window
love.window.restore()
test:assertEquals(false, love.window.isMinimized(), 'check window restored')
-- TODO: for linux runner
-- test doesn't pass because the current test delay system can't wait twice
if test:isDelayed() == false then
-- check minimized to start
love.window.minimize()
love.window.restore()
test:setDelay(10)
else
-- check restoring the state of the window
test:assertEquals(false, love.window.isMinimized(), 'check window restored')
end
end
@@ -305,11 +327,15 @@ end
-- love.window.setPosition
love.test.window.setPosition = function(test)
-- check position is returned
love.window.setPosition(100, 100, 1)
local x, y, _ = love.window.getPosition()
test:assertEquals(100, x, 'check position x')
test:assertEquals(100, y, 'check position y')
if test:isDelayed() == false then
-- check position is returned
love.window.setPosition(100, 100, 1)
test:setDelay(10)
else
local x, y, _ = love.window.getPosition()
test:assertEquals(100, x, 'check position x')
test:assertEquals(100, y, 'check position y')
end
end
@@ -324,12 +350,8 @@ end
-- love.window.setVSync
love.test.window.setVSync = function(test)
-- check setting vsync value off
love.window.setVSync(0)
test:assertEquals(0, love.window.getVSync(), 'check vsync off')
-- check setting vsync value on
love.window.setVSync(1)
test:assertEquals(1, love.window.getVSync(), 'check vsync on')
test:assertNotNil(love.window.getVSync())
end
+19 -24
View File
@@ -1,31 +1,26 @@
`/Applications/love_12.app/Contents/MacOS/love ./testing`
## TESTSUITE
- [ ] move object methods to respective modules
- [ ] start object methods
- [ ] setStencilMode to replace setStencilTest
## GENERAL
- [ ] check 12.0 wiki page for new methods
- [ ] change delay system to use coroutines
- [ ] need a platform: format table somewhere for compressed formats (i.e. DXT not supported)
## GRAPHICS
## OBJECT TESTS
- [ ] physics.Body, physics.Contact, physics.Fixture,
physics.Joint, physics.Shape, physics.World
- [ ] threads.Channel, threads.Thread
## METHOD TESTS
- [ ] event.wait
- [ ] graphics.present
- [ ] graphics.drawInstanced
## DEPRECATED
- [ ] deprecated setStencilTest (use setStencilMode)
- [ ] deprecated physics methods
## GRAPHIC TESTS
Methods that need a actual graphic pixel checks if possible:
- [ ] setDepthMode
- [ ] setFrontFaceWinding
- [ ] setMeshCullMode
- [ ] present
- [ ] drawInstanced
## FUTURE
- [ ] need a platform: format table somewhere for compressed formats (i.e. DXT not supported)
- [ ] use coroutines for the delay action? i.e. wrap each test call in coroutine
- [ ] could nil check some joystick and keyboard methods?
## GITHUB ACTION CI
- [ ] linux needs to run xvfb-run with the appimage
- [ ] try vulkan on windows/linux
- [ ] ios test run?
## NOTES
Can't run --renderers metal on github action images:
Run love-macos/love.app/Contents/MacOS/love testing --renderers metal
Cannot create Metal renderer: Metal is not supported on this system.
Cannot create graphics: no supported renderer on this system.
Error: Cannot create graphics: no supported renderer on this system.