Browse Source

latest from love-test

ell 1 year ago
parent
commit
658c75b5c3

+ 11 - 0
.github/workflows/main.yml

@@ -311,33 +311,40 @@ jobs:
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengl
         path: testing/output/lovetest_runAllTests.md
         path: testing/output/lovetest_runAllTests.md
     - name: Zip Test Output (opengl)
     - name: Zip Test Output (opengl)
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       run: |
         7z a -tzip test-output-windows-opengl.zip testing/output/
         7z a -tzip test-output-windows-opengl.zip testing/output/
     - name: Artifact Test Output (opengl)
     - name: Artifact Test Output (opengl)
+      if: steps.vars.outputs.arch != 'ARM64'
       uses: actions/upload-artifact@v3
       uses: actions/upload-artifact@v3
       with:
       with:
         name: test-output-windows-opengl
         name: test-output-windows-opengl
         path: test-output-windows-opengl.zip
         path: test-output-windows-opengl.zip
     # windows opengles test
     # windows opengles test
     - name: Run Tests (opengles)
     - name: Run Tests (opengles)
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       run: |
         $ENV:LOVE_GRAPHICS_USE_OPENGLES=1
         $ENV:LOVE_GRAPHICS_USE_OPENGLES=1
         powershell.exe ./install/lovec.exe ./testing/main.lua
         powershell.exe ./install/lovec.exe ./testing/main.lua
     - name: Love Test Report (opengles)
     - name: Love Test Report (opengles)
+      if: steps.vars.outputs.arch != 'ARM64'
       uses: ellraiser/love-test-report@main
       uses: ellraiser/love-test-report@main
       with:
       with:
         name: Love Testsuite Windows (opengles)
         name: Love Testsuite Windows (opengles)
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-opengles
         path: testing/output/lovetest_runAllTests.md
         path: testing/output/lovetest_runAllTests.md
     - name: Zip Test Output (opengles)
     - name: Zip Test Output (opengles)
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       run: |
         7z a -tzip test-output-windows-opengles.zip testing/output/
         7z a -tzip test-output-windows-opengles.zip testing/output/
     - name: Artifact Test Output (opengles)
     - name: Artifact Test Output (opengles)
+      if: steps.vars.outputs.arch != 'ARM64'
       uses: actions/upload-artifact@v3
       uses: actions/upload-artifact@v3
       with:
       with:
         name: test-output-windows-opengles
         name: test-output-windows-opengles
         path: test-output-windows-opengles.zip
         path: test-output-windows-opengles.zip
     - name: Install Vulkan
     - name: Install Vulkan
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       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
         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 
         ./VulkanSDK.exe --root C:/VulkanSDK/1.3.231.1 --accept-licenses --default-answer --confirm-command install com.lunarg.vulkan.core com.lunarg.vulkan.vma 
@@ -350,19 +357,23 @@ jobs:
         powershell.exe C:/VulkanSDK/1.3.231.1/runtime/x64/vulkaninfo.exe --summary
         powershell.exe C:/VulkanSDK/1.3.231.1/runtime/x64/vulkaninfo.exe --summary
     # windows vulkan tests
     # windows vulkan tests
     - name: Run Tests (vulkan)
     - name: Run Tests (vulkan)
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       run: |
         $ENV:LOVE_GRAPHICS_DEBUG=1
         $ENV:LOVE_GRAPHICS_DEBUG=1
         powershell.exe ./install/lovec.exe ./testing/main.lua --runAllTests --renderers vulkan
         powershell.exe ./install/lovec.exe ./testing/main.lua --runAllTests --renderers vulkan
     - name: Love Test Report (vulkan)
     - name: Love Test Report (vulkan)
+      if: steps.vars.outputs.arch != 'ARM64'
       uses: ellraiser/love-test-report@main
       uses: ellraiser/love-test-report@main
       with:
       with:
         name: Love Testsuite Windows (vulkan)
         name: Love Testsuite Windows (vulkan)
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-vulkan
         title: test-report-windows-${{ steps.vars.outputs.arch }}${{ steps.vars.outputs.compatname }}-vulkan
         path: testing/output/lovetest_runAllTests.md
         path: testing/output/lovetest_runAllTests.md
     - name: Zip Test Output (vulkan)
     - name: Zip Test Output (vulkan)
+      if: steps.vars.outputs.arch != 'ARM64'
       run: |
       run: |
         7z a -tzip test-output-windows-vulkan.zip testing/output
         7z a -tzip test-output-windows-vulkan.zip testing/output
     - name: Artifact Test Output (vulkan)
     - name: Artifact Test Output (vulkan)
+      if: steps.vars.outputs.arch != 'ARM64'
       uses: actions/upload-artifact@v3
       uses: actions/upload-artifact@v3
       with:
       with:
         name: test-output-windows-vulkan
         name: test-output-windows-vulkan

+ 4 - 9
testing/classes/TestMethod.lua

@@ -42,7 +42,8 @@ TestMethod = {
       imgs = 1,
       imgs = 1,
       delay = 0,
       delay = 0,
       delayed = false,
       delayed = false,
-      store = {}
+      store = {},
+      co = nil
     }
     }
     setmetatable(test, self)
     setmetatable(test, self)
     self.__index = self
     self.__index = self
@@ -281,14 +282,8 @@ TestMethod = {
   end,
   end,
 
 
 
 
-  -- currently unused
-  setDelay = function(self, frames)
-    self.delay = frames
-    self.delayed = true
-    love.test.delayed = self
-  end,
-  isDelayed = function(self)
-    return self.delayed
+  waitFrames = function(self, frames)
+    for i=1,frames do coroutine.yield() end
   end,
   end,
 
 
 
 

+ 0 - 2
testing/classes/TestModule.lua

@@ -10,9 +10,7 @@ TestModule = {
   -- @return {table} - returns the new Suite object
   -- @return {table} - returns the new Suite object
   new = function(self, module, method)
   new = function(self, module, method)
     local testmodule = {
     local testmodule = {
-      timer = 0,
       time = 0,
       time = 0,
-      delay = 0.01,
       spacer = '                                        ',
       spacer = '                                        ',
       colors = {
       colors = {
         PASS = 'green', FAIL = 'red', SKIP = 'grey'
         PASS = 'green', FAIL = 'red', SKIP = 'grey'

+ 15 - 37
testing/classes/TestSuite.lua

@@ -59,9 +59,7 @@ TestSuite = {
 
 
       -- stagger between tests
       -- stagger between tests
     if self.module ~= nil then
     if self.module ~= nil then
-      self.module.timer = self.module.timer + delta
-      if self.module.timer >= self.module.delay then
-        self.module.timer = self.module.timer - self.module.delay
+
         if self.module.start == true then
         if self.module.start == true then
 
 
           -- work through each test method 1 by 1
           -- work through each test method 1 by 1
@@ -74,43 +72,25 @@ TestSuite = {
               self.test = TestMethod:new(method, self.module)
               self.test = TestMethod:new(method, self.module)
               TextRun:set('love.' .. self.module.module .. '.' .. method)
               TextRun:set('love.' .. self.module.module .. '.' .. method)
 
 
-              -- check method exists in love first
-              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'],
-                  tested .. matching,
-                  ' ==> FAIL (0/0) - call failed - method does not exist'
-                )
-              -- otherwise run the test method
-              else
-                local ok, chunk, err = pcall(self[self.module.module][method], self.test)
+              self.test.co = coroutine.create(function()
+                local ok, chunk, err = pcall(love.test[love.test.module.module][method], love.test.test)
                 if ok == false then
                 if ok == false then
-                  self.test.passed = false
-                  self.test.fatal = tostring(chunk) .. tostring(err)
+                  love.test.test.passed = false
+                  love.test.test.fatal = tostring(chunk) .. tostring(err)
                 end
                 end
-              end
+              end)
 
 
-            -- once we've run check delay + eval
+
+            -- once called we have a corouting, so just call resume every frame
+            -- until we have finished
             else
             else
 
 
-              -- @TODO use coroutines?
-              -- if we have a test method that needs a delay
-              -- we wait for the delay to run out first
-              if self.delayed ~= nil then
-                self.delayed.delay = self.delayed.delay - 1
-                -- re-run the test method again when delay ends
-                -- its up to the test to handle the :isDelayed() property
-                if self.delayed.delay <= 0 then
-                  local ok, chunk, err = pcall(self[self.module.module][self.delayed.method], self.test)
-                  if ok == false then
-                    self.test.passed = false
-                    self.test.fatal = tostring(chunk) .. tostring(err)
-                  end
-                  self.delayed = nil
-                end
-              else
+              -- move onto next yield if any
+              -- pauses can be set with TestMethod:waitFrames(frames)
+              coroutine.resume(self.test.co)
 
 
+              -- when wait finished (or no yields)
+              if coroutine.status(self.test.co) == 'dead' then
                 -- now we're all done evaluate the test 
                 -- now we're all done evaluate the test 
                 local ok, chunk, err = pcall(self.test.evaluateTest, self.test)
                 local ok, chunk, err = pcall(self.test.evaluateTest, self.test)
                 if ok == false then
                 if ok == false then
@@ -118,11 +98,9 @@ TestSuite = {
                   self.test.fatal = tostring(chunk) .. tostring(err)
                   self.test.fatal = tostring(chunk) .. tostring(err)
                 end
                 end
                 -- save having to :release() anything we made in the last test
                 -- save having to :release() anything we made in the last test
-                -- 7251ms > 7543ms
                 collectgarbage("collect")
                 collectgarbage("collect")
                 -- move onto the next test
                 -- move onto the next test
                 self.module.index = self.module.index + 1
                 self.module.index = self.module.index + 1
-
               end
               end
 
 
             end
             end
@@ -148,7 +126,7 @@ TestSuite = {
           end
           end
         end
         end
       end
       end
-    end
+
   end,
   end,
 
 
 
 

File diff suppressed because it is too large
+ 0 - 0
testing/examples/lovetest_runAllTests.html


+ 23 - 20
testing/examples/lovetest_runAllTests.md

@@ -1,28 +1,31 @@
-<!-- PASSED 254 || FAILED 1 || SKIPPED 50 || TIME 12.195 -->
+<!-- PASSED 275 || FAILED 2 || SKIPPED 28 || TIME 16.781 -->
 
 
-**305** tests were completed in **12.195s** with **254** passed, **1** failed, and **50** skipped
+**305** tests were completed in **16.781s** with **275** passed, **2** failed, and **28** skipped
 
 
 ### Report
 ### Report
-| Module                | Passed | Failed | Skipped | Time   |
+| Module                | Pass | Fail | Skip | Time   |
 | --------------------- | ------ | ------ | ------- | ------ |
 | --------------------- | ------ | ------ | ------- | ------ |
-| 🟢 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 |
+| 🔴 audio | 27 | 1 | 0 | 4.898s |
+| 🟢 data | 12 | 0 | 0 | 0.213s |
+| 🟢 event | 4 | 0 | 2 | 0.103s |
+| 🟢 filesystem | 29 | 0 | 2 | 0.561s |
+| 🔴 font | 6 | 1 | 0 | 0.123s |
+| 🟢 graphics | 93 | 0 | 14 | 2.106s |
+| 🟢 image | 5 | 0 | 0 | 0.088s |
+| 🟢 math | 20 | 0 | 0 | 0.284s |
+| 🟢 physics | 22 | 0 | 6 | 0.059s |
+| 🟢 sound | 4 | 0 | 0 | 0.015s |
+| 🟢 system | 6 | 0 | 2 | 0.023s |
+| 🟢 thread | 5 | 0 | 0 | 0.318s |
+| 🟢 timer | 6 | 0 | 0 | 2.020s |
+| 🟢 video | 2 | 0 | 0 | 0.016s |
+| 🟢 window | 34 | 0 | 2 | 5.954s |
 
 
 
 
 ### Failures
 ### Failures
-> 🔴 setColorMask  
-> assert #7 [check pixel b for yellow at 0,0(set color mask)] expected '0' got '1'  
+> 🔴 Source  
+> assert 53 [check effect was applied] expected 'true' got 'false'  
+
+> 🔴 GlyphData  
+> assert 8 [check glyph number] expected '97' got '0'  
 
 

+ 256 - 277
testing/examples/lovetest_runAllTests.xml

@@ -1,122 +1,115 @@
-<testsuites name="love.test" tests="254" failures="1" skipped="50" time="12.195">
-	<testsuite name="love.audio" tests="26" failures="0" skipped="2" time="0.473">
-		<testcase classname="RecordingDevice" name="RecordingDevice" assertions="0" time="0.024">
-			<skipped message="test class needs writing" />
+<testsuites name="love.test" tests="275" failures="2" skipped="28" time="16.781">
+	<testsuite name="love.audio" tests="27" failures="1" skipped="0" time="4.898">
+		<testcase classname="RecordingDevice" name="RecordingDevice" assertions="20" time="4.419">
 		</testcase>
 		</testcase>
-		<testcase classname="Source" name="Source" assertions="0" time="0.017">
-			<skipped message="test class needs writing" />
+		<testcase classname="Source" name="Source" assertions="54" time="0.019">
+			<failure message="assert 53 [check effect was applied] expected 'true' got 'false'">assert 53 [check effect was applied] expected 'true' got 'false'</failure>
 		</testcase>
 		</testcase>
-		<testcase classname="getActiveEffects" name="getActiveEffects" assertions="3" time="0.016">
+		<testcase classname="getActiveEffects" name="getActiveEffects" assertions="3" time="0.013">
 		</testcase>
 		</testcase>
-		<testcase classname="getActiveSourceCount" name="getActiveSourceCount" assertions="3" time="0.016">
+		<testcase classname="getActiveSourceCount" name="getActiveSourceCount" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getDistanceModel" name="getDistanceModel" assertions="3" time="0.017">
+		<testcase classname="getDistanceModel" name="getDistanceModel" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getDopplerScale" name="getDopplerScale" assertions="2" time="0.016">
+		<testcase classname="getDopplerScale" name="getDopplerScale" assertions="2" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="getEffect" name="getEffect" assertions="4" time="0.016">
+		<testcase classname="getEffect" name="getEffect" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="getMaxSceneEffects" name="getMaxSceneEffects" assertions="1" time="0.017">
 		<testcase classname="getMaxSceneEffects" name="getMaxSceneEffects" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getMaxSourceEffects" name="getMaxSourceEffects" assertions="1" time="0.015">
+		<testcase classname="getMaxSourceEffects" name="getMaxSourceEffects" assertions="1" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="getOrientation" name="getOrientation" assertions="6" time="0.017">
+		<testcase classname="getOrientation" name="getOrientation" assertions="6" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="getPosition" name="getPosition" assertions="3" time="0.017">
 		<testcase classname="getPosition" name="getPosition" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getRecordingDevices" name="getRecordingDevices" assertions="1" time="0.017">
 		<testcase classname="getRecordingDevices" name="getRecordingDevices" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getVelocity" name="getVelocity" assertions="3" time="0.016">
+		<testcase classname="getVelocity" name="getVelocity" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getVolume" name="getVolume" assertions="1" time="0.017">
+		<testcase classname="getVolume" name="getVolume" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="isEffectsSupported" name="isEffectsSupported" assertions="1" time="0.016">
+		<testcase classname="isEffectsSupported" name="isEffectsSupported" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="newQueueableSource" name="newQueueableSource" assertions="3" time="0.015">
+		<testcase classname="newQueueableSource" name="newQueueableSource" assertions="3" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="newSource" name="newSource" assertions="6" time="0.014">
+		<testcase classname="newSource" name="newSource" assertions="6" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="pause" name="pause" assertions="2" time="0.016">
+		<testcase classname="pause" name="pause" assertions="2" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="play" name="play" assertions="1" time="0.017">
+		<testcase classname="play" name="play" assertions="1" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="setDistanceModel" name="setDistanceModel" assertions="7" time="0.019">
 		<testcase classname="setDistanceModel" name="setDistanceModel" assertions="7" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="setDopplerScale" name="setDopplerScale" assertions="2" time="0.017">
+		<testcase classname="setDopplerScale" name="setDopplerScale" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="setEffect" name="setEffect" assertions="3" time="0.017">
 		<testcase classname="setEffect" name="setEffect" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="setMixWithSystem" name="setMixWithSystem" assertions="1" time="0.017">
 		<testcase classname="setMixWithSystem" name="setMixWithSystem" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="setOrientation" name="setOrientation" assertions="6" time="0.017">
+		<testcase classname="setOrientation" name="setOrientation" assertions="6" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="setPosition" name="setPosition" assertions="3" time="0.018">
+		<testcase classname="setPosition" name="setPosition" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="setVelocity" name="setVelocity" assertions="3" time="0.017">
+		<testcase classname="setVelocity" name="setVelocity" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setVolume" name="setVolume" assertions="1" time="0.016">
+		<testcase classname="setVolume" name="setVolume" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="stop" name="stop" assertions="2" time="0.018">
+		<testcase classname="stop" name="stop" assertions="2" time="0.019">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.data" tests="7" failures="0" skipped="5" time="0.212">
-		<testcase classname="ByteData" name="ByteData" assertions="0" time="0.016">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.data" tests="12" failures="0" skipped="0" time="0.213">
+		<testcase classname="ByteData" name="ByteData" assertions="10" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="CompressedData" name="CompressedData" assertions="0" time="0.017">
-			<skipped message="test class needs writing" />
+		<testcase classname="CompressedData" name="CompressedData" assertions="12" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="compress" name="compress" assertions="45" time="0.017">
+		<testcase classname="compress" name="compress" assertions="45" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="decode" name="decode" assertions="4" time="0.018">
 		<testcase classname="decode" name="decode" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="decompress" name="decompress" assertions="18" time="0.018">
 		<testcase classname="decompress" name="decompress" assertions="18" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="encode" name="encode" assertions="15" time="0.019">
+		<testcase classname="encode" name="encode" assertions="15" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getPackedSize" name="getPackedSize" assertions="0" time="0.019">
-			<skipped message="test class needs writing" />
+		<testcase classname="getPackedSize" name="getPackedSize" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="hash" name="hash" assertions="6" time="0.017">
+		<testcase classname="hash" name="hash" assertions="6" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="newByteData" name="newByteData" assertions="3" time="0.017">
 		<testcase classname="newByteData" name="newByteData" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="newDataView" name="newDataView" assertions="3" time="0.017">
 		<testcase classname="newDataView" name="newDataView" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="pack" name="pack" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="pack" name="pack" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="unpack" name="unpack" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="unpack" name="unpack" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.event" tests="4" failures="0" skipped="2" time="0.108">
-		<testcase classname="clear" name="clear" assertions="1" time="0.017">
+	<testsuite name="love.event" tests="4" failures="0" skipped="2" time="0.103">
+		<testcase classname="clear" name="clear" assertions="1" time="0.015">
 		</testcase>
 		</testcase>
 		<testcase classname="poll" name="poll" assertions="1" time="0.017">
 		<testcase classname="poll" name="poll" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="pump" name="pump" assertions="0" time="0.019">
-			<skipped message="not sure can be tested as used internally" />
+		<testcase classname="pump" name="pump" assertions="0" time="0.018">
+			<skipped message="used internally" />
 		</testcase>
 		</testcase>
 		<testcase classname="push" name="push" assertions="1" time="0.018">
 		<testcase classname="push" name="push" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="quit" name="quit" assertions="1" time="0.019">
+		<testcase classname="quit" name="quit" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="wait" name="wait" assertions="0" time="0.018">
+		<testcase classname="wait" name="wait" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.filesystem" tests="28" failures="0" skipped="3" time="0.556">
-		<testcase classname="File" name="File" assertions="36" time="0.017">
+	<testsuite name="love.filesystem" tests="29" failures="0" skipped="2" time="0.561">
+		<testcase classname="File" name="File" assertions="36" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="FileData" name="FileData" assertions="0" time="0.019">
-			<skipped message="test class needs writing" />
+		<testcase classname="FileData" name="FileData" assertions="12" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="append" name="append" assertions="6" time="0.019">
+		<testcase classname="append" name="append" assertions="6" time="0.020">
 		</testcase>
 		</testcase>
 		<testcase classname="areSymlinksEnabled" name="areSymlinksEnabled" assertions="1" time="0.017">
 		<testcase classname="areSymlinksEnabled" name="areSymlinksEnabled" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="createDirectory" name="createDirectory" assertions="3" time="0.017">
+		<testcase classname="createDirectory" name="createDirectory" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="getAppdataDirectory" name="getAppdataDirectory" assertions="1" time="0.018">
 		<testcase classname="getAppdataDirectory" name="getAppdataDirectory" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
@@ -124,91 +117,89 @@
 		</testcase>
 		</testcase>
 		<testcase classname="getDirectoryItems" name="getDirectoryItems" assertions="2" time="0.018">
 		<testcase classname="getDirectoryItems" name="getDirectoryItems" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getIdentity" name="getIdentity" assertions="1" time="0.019">
+		<testcase classname="getIdentity" name="getIdentity" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="getInfo" name="getInfo" assertions="3" time="0.019">
 		<testcase classname="getInfo" name="getInfo" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="getRealDirectory" name="getRealDirectory" assertions="1" time="0.018">
 		<testcase classname="getRealDirectory" name="getRealDirectory" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getRequirePath" name="getRequirePath" assertions="1" time="0.018">
+		<testcase classname="getRequirePath" name="getRequirePath" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getSaveDirectory" name="getSaveDirectory" assertions="1" time="0.018">
+		<testcase classname="getSaveDirectory" name="getSaveDirectory" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getSource" name="getSource" assertions="0" time="0.018">
-			<skipped message="not sure can be tested as used internally" />
+		<testcase classname="getSource" name="getSource" assertions="0" time="0.016">
+			<skipped message="used internally" />
 		</testcase>
 		</testcase>
 		<testcase classname="getSourceBaseDirectory" name="getSourceBaseDirectory" assertions="1" time="0.018">
 		<testcase classname="getSourceBaseDirectory" name="getSourceBaseDirectory" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getUserDirectory" name="getUserDirectory" assertions="1" time="0.019">
+		<testcase classname="getUserDirectory" name="getUserDirectory" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getWorkingDirectory" name="getWorkingDirectory" assertions="1" time="0.019">
+		<testcase classname="getWorkingDirectory" name="getWorkingDirectory" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="isFused" name="isFused" assertions="1" time="0.017">
+		<testcase classname="isFused" name="isFused" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="lines" name="lines" assertions="6" time="0.018">
+		<testcase classname="lines" name="lines" assertions="6" time="0.022">
 		</testcase>
 		</testcase>
-		<testcase classname="load" name="load" assertions="4" time="0.016">
+		<testcase classname="load" name="load" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="mount" name="mount" assertions="5" time="0.019">
+		<testcase classname="mount" name="mount" assertions="5" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="newFileData" name="newFileData" assertions="1" time="0.018">
 		<testcase classname="newFileData" name="newFileData" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="openFile" name="openFile" assertions="4" time="0.019">
+		<testcase classname="openFile" name="openFile" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="read" name="read" assertions="6" time="0.017">
+		<testcase classname="read" name="read" assertions="6" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="remove" name="remove" assertions="5" time="0.018">
 		<testcase classname="remove" name="remove" assertions="5" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="setCRequirePath" name="setCRequirePath" assertions="1" time="0.018">
 		<testcase classname="setCRequirePath" name="setCRequirePath" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setIdentity" name="setIdentity" assertions="1" time="0.018">
+		<testcase classname="setIdentity" name="setIdentity" assertions="1" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="setRequirePath" name="setRequirePath" assertions="1" time="0.018">
+		<testcase classname="setRequirePath" name="setRequirePath" assertions="1" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="setSource" name="setSource" assertions="0" time="0.018">
-			<skipped message="not sure can be tested as used internally" />
+		<testcase classname="setSource" name="setSource" assertions="0" time="0.017">
+			<skipped message="used internally" />
 		</testcase>
 		</testcase>
 		<testcase classname="unmount" name="unmount" assertions="2" time="0.018">
 		<testcase classname="unmount" name="unmount" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="write" name="write" assertions="3" time="0.019">
 		<testcase classname="write" name="write" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.font" tests="4" failures="0" skipped="3" time="0.127">
-		<testcase classname="GlyphData" name="GlyphData" assertions="0" time="0.017">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.font" tests="6" failures="1" skipped="0" time="0.123">
+		<testcase classname="GlyphData" name="GlyphData" assertions="19" time="0.017">
+			<failure message="assert 8 [check glyph number] expected '97' got '0'">assert 8 [check glyph number] expected '97' got '0'</failure>
 		</testcase>
 		</testcase>
-		<testcase classname="Rasterizer" name="Rasterizer" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="Rasterizer" name="Rasterizer" assertions="13" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newBMFontRasterizer" name="newBMFontRasterizer" assertions="0" time="0.018">
-			<skipped message="wiki and source dont match, not sure expected usage" />
+		<testcase classname="newBMFontRasterizer" name="newBMFontRasterizer" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newGlyphData" name="newGlyphData" assertions="3" time="0.020">
+		<testcase classname="newGlyphData" name="newGlyphData" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newImageRasterizer" name="newImageRasterizer" assertions="3" time="0.020">
+		<testcase classname="newImageRasterizer" name="newImageRasterizer" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newRasterizer" name="newRasterizer" assertions="3" time="0.018">
+		<testcase classname="newRasterizer" name="newRasterizer" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="newTrueTypeRasterizer" name="newTrueTypeRasterizer" assertions="6" time="0.017">
+		<testcase classname="newTrueTypeRasterizer" name="newTrueTypeRasterizer" assertions="6" time="0.019">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.graphics" tests="91" failures="1" skipped="15" time="2.091">
-		<testcase classname="Canvas" name="Canvas" assertions="0" time="0.016">
+	<testsuite name="love.graphics" tests="93" failures="0" skipped="14" time="2.106">
+		<testcase classname="Canvas" name="Canvas" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Font" name="Font" assertions="0" time="0.017">
+		<testcase classname="Font" name="Font" assertions="0" time="0.018">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Image" name="Image" assertions="0" time="0.019">
+		<testcase classname="Image" name="Image" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Mesh" name="Mesh" assertions="0" time="0.019">
+		<testcase classname="Mesh" name="Mesh" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
 		<testcase classname="ParticleSystem" name="ParticleSystem" assertions="0" time="0.017">
 		<testcase classname="ParticleSystem" name="ParticleSystem" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Quad" name="Quad" assertions="0" time="0.019">
+		<testcase classname="Quad" name="Quad" assertions="0" time="0.017">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
 		<testcase classname="Shader" name="Shader" assertions="0" time="0.018">
 		<testcase classname="Shader" name="Shader" assertions="0" time="0.018">
@@ -223,65 +214,64 @@
 		<testcase classname="Texture" name="Texture" assertions="0" time="0.018">
 		<testcase classname="Texture" name="Texture" assertions="0" time="0.018">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Video" name="Video" assertions="0" time="0.019">
+		<testcase classname="Video" name="Video" assertions="0" time="0.007">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="applyTransform" name="applyTransform" assertions="4" time="0.018">
+		<testcase classname="applyTransform" name="applyTransform" assertions="4" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="arc" name="arc" assertions="264" time="0.018">
+		<testcase classname="arc" name="arc" assertions="264" time="0.024">
 		</testcase>
 		</testcase>
-		<testcase classname="captureScreenshot" name="captureScreenshot" assertions="1" time="0.183">
+		<testcase classname="captureScreenshot" name="captureScreenshot" assertions="1" time="0.184">
 		</testcase>
 		</testcase>
-		<testcase classname="circle" name="circle" assertions="192" time="0.017">
+		<testcase classname="circle" name="circle" assertions="192" time="0.021">
 		</testcase>
 		</testcase>
-		<testcase classname="clear" name="clear" assertions="20" time="0.017">
+		<testcase classname="clear" name="clear" assertions="20" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="discard" name="discard" assertions="0" time="0.017">
+		<testcase classname="discard" name="discard" assertions="0" time="0.016">
 			<skipped message="cant test this worked" />
 			<skipped message="cant test this worked" />
 		</testcase>
 		</testcase>
 		<testcase classname="draw" name="draw" assertions="112" time="0.018">
 		<testcase classname="draw" name="draw" assertions="112" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="drawInstanced" name="drawInstanced" assertions="0" time="0.020">
+		<testcase classname="drawInstanced" name="drawInstanced" assertions="0" time="0.018">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="drawLayer" name="drawLayer" assertions="144" time="0.018">
+		<testcase classname="drawLayer" name="drawLayer" assertions="144" time="0.020">
 		</testcase>
 		</testcase>
 		<testcase classname="ellipse" name="ellipse" assertions="80" time="0.018">
 		<testcase classname="ellipse" name="ellipse" assertions="80" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="flushBatch" name="flushBatch" assertions="0" time="0.018">
-			<skipped message="not sure can be tested as used internally" />
+		<testcase classname="flushBatch" name="flushBatch" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getBackgroundColor" name="getBackgroundColor" assertions="8" time="0.018">
 		<testcase classname="getBackgroundColor" name="getBackgroundColor" assertions="8" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="getBlendMode" name="getBlendMode" assertions="4" time="0.018">
 		<testcase classname="getBlendMode" name="getBlendMode" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getCanvas" name="getCanvas" assertions="4" time="0.018">
+		<testcase classname="getCanvas" name="getCanvas" assertions="4" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="getColor" name="getColor" assertions="8" time="0.017">
 		<testcase classname="getColor" name="getColor" assertions="8" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getColorMask" name="getColorMask" assertions="8" time="0.018">
 		<testcase classname="getColorMask" name="getColorMask" assertions="8" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getDPIScale" name="getDPIScale" assertions="1" time="0.019">
+		<testcase classname="getDPIScale" name="getDPIScale" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getDefaultFilter" name="getDefaultFilter" assertions="3" time="0.018">
 		<testcase classname="getDefaultFilter" name="getDefaultFilter" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getDepthMode" name="getDepthMode" assertions="2" time="0.018">
+		<testcase classname="getDepthMode" name="getDepthMode" assertions="2" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getDimensions" name="getDimensions" assertions="2" time="0.017">
+		<testcase classname="getDimensions" name="getDimensions" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getFont" name="getFont" assertions="3" time="0.018">
+		<testcase classname="getFont" name="getFont" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="getFrontFaceWinding" name="getFrontFaceWinding" assertions="2" time="0.019">
+		<testcase classname="getFrontFaceWinding" name="getFrontFaceWinding" assertions="2" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getHeight" name="getHeight" assertions="1" time="0.017">
 		<testcase classname="getHeight" name="getHeight" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getLineJoin" name="getLineJoin" assertions="2" time="0.018">
+		<testcase classname="getLineJoin" name="getLineJoin" assertions="2" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getLineStyle" name="getLineStyle" assertions="2" time="0.017">
+		<testcase classname="getLineStyle" name="getLineStyle" assertions="2" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="getLineWidth" name="getLineWidth" assertions="2" time="0.019">
+		<testcase classname="getLineWidth" name="getLineWidth" assertions="2" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="getMeshCullMode" name="getMeshCullMode" assertions="2" time="0.018">
+		<testcase classname="getMeshCullMode" name="getMeshCullMode" assertions="2" time="0.016">
 		</testcase>
 		</testcase>
 		<testcase classname="getPixelDimensions" name="getPixelDimensions" assertions="2" time="0.018">
 		<testcase classname="getPixelDimensions" name="getPixelDimensions" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
@@ -289,107 +279,106 @@
 		</testcase>
 		</testcase>
 		<testcase classname="getPixelWidth" name="getPixelWidth" assertions="1" time="0.018">
 		<testcase classname="getPixelWidth" name="getPixelWidth" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getPointSize" name="getPointSize" assertions="2" time="0.019">
+		<testcase classname="getPointSize" name="getPointSize" assertions="2" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="getRendererInfo" name="getRendererInfo" assertions="4" time="0.018">
+		<testcase classname="getRendererInfo" name="getRendererInfo" assertions="4" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="getScissor" name="getScissor" assertions="8" time="0.018">
+		<testcase classname="getScissor" name="getScissor" assertions="8" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getShader" name="getShader" assertions="1" time="0.018">
+		<testcase classname="getShader" name="getShader" assertions="1" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="getStackDepth" name="getStackDepth" assertions="4" time="0.018">
 		<testcase classname="getStackDepth" name="getStackDepth" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getStats" name="getStats" assertions="7" time="0.017">
+		<testcase classname="getStats" name="getStats" assertions="7" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getStencilMode" name="getStencilMode" assertions="6" time="0.018">
+		<testcase classname="getStencilMode" name="getStencilMode" assertions="6" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getSupported" name="getSupported" assertions="17" time="0.018">
 		<testcase classname="getSupported" name="getSupported" assertions="17" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getSystemLimits" name="getSystemLimits" assertions="13" time="0.019">
+		<testcase classname="getSystemLimits" name="getSystemLimits" assertions="13" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getTextureFormats" name="getTextureFormats" assertions="79" time="0.020">
+		<testcase classname="getTextureFormats" name="getTextureFormats" assertions="79" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="getTextureTypes" name="getTextureTypes" assertions="4" time="0.017">
+		<testcase classname="getTextureTypes" name="getTextureTypes" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getWidth" name="getWidth" assertions="1" time="0.018">
+		<testcase classname="getWidth" name="getWidth" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="intersectScissor" name="intersectScissor" assertions="20" time="0.018">
+		<testcase classname="intersectScissor" name="intersectScissor" assertions="20" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="inverseTransformPoint" name="inverseTransformPoint" assertions="4" time="0.018">
+		<testcase classname="inverseTransformPoint" name="inverseTransformPoint" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="isActive" name="isActive" assertions="1" time="0.018">
+		<testcase classname="isActive" name="isActive" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="isGammaCorrect" name="isGammaCorrect" assertions="1" time="0.019">
+		<testcase classname="isGammaCorrect" name="isGammaCorrect" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="isWireframe" name="isWireframe" assertions="2" time="0.017">
+		<testcase classname="isWireframe" name="isWireframe" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="line" name="line" assertions="64" time="0.016">
+		<testcase classname="line" name="line" assertions="64" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="newArrayImage" name="newArrayImage" assertions="3" time="0.018">
+		<testcase classname="newArrayImage" name="newArrayImage" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="newCanvas" name="newCanvas" assertions="6" time="0.019">
+		<testcase classname="newCanvas" name="newCanvas" assertions="6" time="0.015">
 		</testcase>
 		</testcase>
-		<testcase classname="newCubeImage" name="newCubeImage" assertions="3" time="0.019">
+		<testcase classname="newCubeImage" name="newCubeImage" assertions="3" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="newFont" name="newFont" assertions="6" time="0.019">
+		<testcase classname="newFont" name="newFont" assertions="6" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newImage" name="newImage" assertions="3" time="0.018">
+		<testcase classname="newImage" name="newImage" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="newImageFont" name="newImageFont" assertions="3" time="0.017">
+		<testcase classname="newImageFont" name="newImageFont" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="newMesh" name="newMesh" assertions="3" time="0.018">
 		<testcase classname="newMesh" name="newMesh" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newParticleSystem" name="newParticleSystem" assertions="3" time="0.019">
+		<testcase classname="newParticleSystem" name="newParticleSystem" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newQuad" name="newQuad" assertions="3" time="0.018">
+		<testcase classname="newQuad" name="newQuad" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="newShader" name="newShader" assertions="3" time="0.018">
+		<testcase classname="newShader" name="newShader" assertions="3" time="0.022">
 		</testcase>
 		</testcase>
-		<testcase classname="newSpriteBatch" name="newSpriteBatch" assertions="3" time="0.018">
+		<testcase classname="newSpriteBatch" name="newSpriteBatch" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="newTextBatch" name="newTextBatch" assertions="3" time="0.017">
+		<testcase classname="newTextBatch" name="newTextBatch" assertions="3" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="newVideo" name="newVideo" assertions="3" time="0.017">
+		<testcase classname="newVideo" name="newVideo" assertions="3" time="0.021">
 		</testcase>
 		</testcase>
-		<testcase classname="newVolumeImage" name="newVolumeImage" assertions="3" time="0.018">
+		<testcase classname="newVolumeImage" name="newVolumeImage" assertions="3" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="origin" name="origin" assertions="4" time="0.018">
 		<testcase classname="origin" name="origin" assertions="4" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="points" name="points" assertions="48" time="0.018">
+		<testcase classname="points" name="points" assertions="48" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="polygon" name="polygon" assertions="56" time="0.018">
+		<testcase classname="polygon" name="polygon" assertions="56" time="0.016">
 		</testcase>
 		</testcase>
 		<testcase classname="pop" name="pop" assertions="4" time="0.019">
 		<testcase classname="pop" name="pop" assertions="4" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="present" name="present" assertions="0" time="0.018">
 		<testcase classname="present" name="present" assertions="0" time="0.018">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="print" name="print" assertions="148" time="0.017">
+		<testcase classname="print" name="print" assertions="148" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="printf" name="printf" assertions="180" time="0.018">
+		<testcase classname="printf" name="printf" assertions="180" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="push" name="push" assertions="4" time="0.018">
+		<testcase classname="push" name="push" assertions="4" time="0.021">
 		</testcase>
 		</testcase>
 		<testcase classname="rectangle" name="rectangle" assertions="116" time="0.018">
 		<testcase classname="rectangle" name="rectangle" assertions="116" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="replaceTransform" name="replaceTransform" assertions="4" time="0.018">
+		<testcase classname="replaceTransform" name="replaceTransform" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="reset" name="reset" assertions="3" time="0.019">
+		<testcase classname="reset" name="reset" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="rotate" name="rotate" assertions="16" time="0.019">
+		<testcase classname="rotate" name="rotate" assertions="16" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="scale" name="scale" assertions="16" time="0.017">
+		<testcase classname="scale" name="scale" assertions="16" time="0.020">
 		</testcase>
 		</testcase>
 		<testcase classname="setBackgroundColor" name="setBackgroundColor" assertions="4" time="0.017">
 		<testcase classname="setBackgroundColor" name="setBackgroundColor" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="setBlendMode" name="setBlendMode" assertions="16" time="0.017">
+		<testcase classname="setBlendMode" name="setBlendMode" assertions="16" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="setCanvas" name="setCanvas" assertions="19" time="0.018">
+		<testcase classname="setCanvas" name="setCanvas" assertions="19" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="setColor" name="setColor" assertions="68" time="0.018">
 		<testcase classname="setColor" name="setColor" assertions="68" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setColorMask" name="setColorMask" assertions="20" time="0.018">
-			<failure message="assert #7 [check pixel b for yellow at 0,0(set color mask)] expected '0' got '1'">assert #7 [check pixel b for yellow at 0,0(set color mask)] expected '0' got '1'</failure>
+		<testcase classname="setColorMask" name="setColorMask" assertions="20" time="0.019">
 		</testcase>
 		</testcase>
 		<testcase classname="setDefaultFilter" name="setDefaultFilter" assertions="3" time="0.018">
 		<testcase classname="setDefaultFilter" name="setDefaultFilter" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
@@ -397,11 +386,11 @@
 		</testcase>
 		</testcase>
 		<testcase classname="setFont" name="setFont" assertions="40" time="0.018">
 		<testcase classname="setFont" name="setFont" assertions="40" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setFrontFaceWinding" name="setFrontFaceWinding" assertions="2" time="0.019">
+		<testcase classname="setFrontFaceWinding" name="setFrontFaceWinding" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setLineJoin" name="setLineJoin" assertions="16" time="0.017">
+		<testcase classname="setLineJoin" name="setLineJoin" assertions="16" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="setLineStyle" name="setLineStyle" assertions="24" time="0.018">
+		<testcase classname="setLineStyle" name="setLineStyle" assertions="24" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="setLineWidth" name="setLineWidth" assertions="72" time="0.018">
 		<testcase classname="setLineWidth" name="setLineWidth" assertions="72" time="0.018">
 		</testcase>
 		</testcase>
@@ -409,285 +398,275 @@
 		</testcase>
 		</testcase>
 		<testcase classname="setScissor" name="setScissor" assertions="32" time="0.018">
 		<testcase classname="setScissor" name="setScissor" assertions="32" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setShader" name="setShader" assertions="16" time="0.018">
+		<testcase classname="setShader" name="setShader" assertions="16" time="0.024">
 		</testcase>
 		</testcase>
 		<testcase classname="setStencilTest" name="setStencilTest" assertions="32" time="0.018">
 		<testcase classname="setStencilTest" name="setStencilTest" assertions="32" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="setWireframe" name="setWireframe" assertions="28" time="0.016">
+		<testcase classname="setWireframe" name="setWireframe" assertions="28" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="shear" name="shear" assertions="32" time="0.018">
+		<testcase classname="shear" name="shear" assertions="32" time="0.021">
 		</testcase>
 		</testcase>
-		<testcase classname="transformPoint" name="transformPoint" assertions="4" time="0.018">
+		<testcase classname="transformPoint" name="transformPoint" assertions="4" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="translate" name="translate" assertions="16" time="0.019">
+		<testcase classname="translate" name="translate" assertions="16" time="0.020">
 		</testcase>
 		</testcase>
-		<testcase classname="validateShader" name="validateShader" assertions="2" time="0.019">
+		<testcase classname="validateShader" name="validateShader" assertions="2" time="0.021">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.image" tests="3" failures="0" skipped="2" time="0.087">
-		<testcase classname="CompressedImageData" name="CompressedImageData" assertions="0" time="0.015">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.image" tests="5" failures="0" skipped="0" time="0.088">
+		<testcase classname="CompressedImageData" name="CompressedImageData" assertions="11" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="ImageData" name="ImageData" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="ImageData" name="ImageData" assertions="14" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="isCompressed" name="isCompressed" assertions="1" time="0.019">
+		<testcase classname="isCompressed" name="isCompressed" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="newCompressedData" name="newCompressedData" assertions="3" time="0.017">
+		<testcase classname="newCompressedData" name="newCompressedData" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="newImageData" name="newImageData" assertions="6" time="0.018">
 		<testcase classname="newImageData" name="newImageData" assertions="6" time="0.018">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.math" tests="17" failures="0" skipped="3" time="0.358">
-		<testcase classname="BezierCurve" name="BezierCurve" assertions="0" time="0.016">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.math" tests="20" failures="0" skipped="0" time="0.284">
+		<testcase classname="BezierCurve" name="BezierCurve" assertions="31" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="RandomGenerator" name="RandomGenerator" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="RandomGenerator" name="RandomGenerator" assertions="10" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="Transform" name="Transform" assertions="0" time="0.019">
-			<skipped message="test class needs writing" />
+		<testcase classname="Transform" name="Transform" assertions="14" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="colorFromBytes" name="colorFromBytes" assertions="12" time="0.017">
+		<testcase classname="colorFromBytes" name="colorFromBytes" assertions="12" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="colorToBytes" name="colorToBytes" assertions="12" time="0.018">
 		<testcase classname="colorToBytes" name="colorToBytes" assertions="12" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="gammaToLinear" name="gammaToLinear" assertions="3" time="0.017">
 		<testcase classname="gammaToLinear" name="gammaToLinear" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getRandomSeed" name="getRandomSeed" assertions="2" time="0.018">
+		<testcase classname="getRandomSeed" name="getRandomSeed" assertions="2" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getRandomState" name="getRandomState" assertions="1" time="0.017">
+		<testcase classname="getRandomState" name="getRandomState" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="isConvex" name="isConvex" assertions="2" time="0.018">
 		<testcase classname="isConvex" name="isConvex" assertions="2" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="linearToGamma" name="linearToGamma" assertions="3" time="0.017">
+		<testcase classname="linearToGamma" name="linearToGamma" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="newBezierCurve" name="newBezierCurve" assertions="3" time="0.018">
 		<testcase classname="newBezierCurve" name="newBezierCurve" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="newRandomGenerator" name="newRandomGenerator" assertions="3" time="0.018">
 		<testcase classname="newRandomGenerator" name="newRandomGenerator" assertions="3" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="newTransform" name="newTransform" assertions="3" time="0.020">
+		<testcase classname="newTransform" name="newTransform" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="perlinNoise" name="perlinNoise" assertions="4" time="0.018">
+		<testcase classname="perlinNoise" name="perlinNoise" assertions="4" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="random" name="random" assertions="10" time="0.019">
+		<testcase classname="random" name="random" assertions="10" time="0.012">
 		</testcase>
 		</testcase>
 		<testcase classname="randomNormal" name="randomNormal" assertions="1" time="0.017">
 		<testcase classname="randomNormal" name="randomNormal" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="setRandomSeed" name="setRandomSeed" assertions="2" time="0.018">
+		<testcase classname="setRandomSeed" name="setRandomSeed" assertions="2" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="setRandomState" name="setRandomState" assertions="1" time="0.018">
+		<testcase classname="setRandomState" name="setRandomState" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="simplexNoise" name="simplexNoise" assertions="4" time="0.018">
+		<testcase classname="simplexNoise" name="simplexNoise" assertions="4" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="triangulate" name="triangulate" assertions="2" time="0.018">
+		<testcase classname="triangulate" name="triangulate" assertions="2" time="0.003">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.physics" tests="22" failures="0" skipped="6" time="0.492">
-		<testcase classname="Body" name="Body" assertions="0" time="0.015">
+	<testsuite name="love.physics" tests="22" failures="0" skipped="6" time="0.059">
+		<testcase classname="Body" name="Body" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Contact" name="Contact" assertions="0" time="0.017">
+		<testcase classname="Contact" name="Contact" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Fixture" name="Fixture" assertions="0" time="0.017">
+		<testcase classname="Fixture" name="Fixture" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Joint" name="Joint" assertions="0" time="0.018">
+		<testcase classname="Joint" name="Joint" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="Shape" name="Shape" assertions="0" time="0.018">
+		<testcase classname="Shape" name="Shape" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="World" name="World" assertions="0" time="0.018">
+		<testcase classname="World" name="World" assertions="0" time="0.002">
 			<skipped message="test class needs writing" />
 			<skipped message="test class needs writing" />
 		</testcase>
 		</testcase>
-		<testcase classname="getDistance" name="getDistance" assertions="1" time="0.017">
+		<testcase classname="getDistance" name="getDistance" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getMeter" name="getMeter" assertions="1" time="0.016">
+		<testcase classname="getMeter" name="getMeter" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newBody" name="newBody" assertions="3" time="0.017">
+		<testcase classname="newBody" name="newBody" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newChainShape" name="newChainShape" assertions="3" time="0.018">
+		<testcase classname="newChainShape" name="newChainShape" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newCircleShape" name="newCircleShape" assertions="3" time="0.019">
+		<testcase classname="newCircleShape" name="newCircleShape" assertions="3" time="0.005">
 		</testcase>
 		</testcase>
-		<testcase classname="newDistanceJoint" name="newDistanceJoint" assertions="3" time="0.018">
+		<testcase classname="newDistanceJoint" name="newDistanceJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newEdgeShape" name="newEdgeShape" assertions="3" time="0.017">
+		<testcase classname="newEdgeShape" name="newEdgeShape" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newFixture" name="newFixture" assertions="3" time="0.019">
+		<testcase classname="newFixture" name="newFixture" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newFrictionJoint" name="newFrictionJoint" assertions="3" time="0.019">
+		<testcase classname="newFrictionJoint" name="newFrictionJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newGearJoint" name="newGearJoint" assertions="3" time="0.019">
+		<testcase classname="newGearJoint" name="newGearJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newMotorJoint" name="newMotorJoint" assertions="3" time="0.018">
+		<testcase classname="newMotorJoint" name="newMotorJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newMouseJoint" name="newMouseJoint" assertions="3" time="0.017">
+		<testcase classname="newMouseJoint" name="newMouseJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newPolygonShape" name="newPolygonShape" assertions="3" time="0.017">
+		<testcase classname="newPolygonShape" name="newPolygonShape" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newPrismaticJoint" name="newPrismaticJoint" assertions="3" time="0.017">
+		<testcase classname="newPrismaticJoint" name="newPrismaticJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newPulleyJoint" name="newPulleyJoint" assertions="3" time="0.017">
+		<testcase classname="newPulleyJoint" name="newPulleyJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newRectangleShape" name="newRectangleShape" assertions="6" time="0.018">
+		<testcase classname="newRectangleShape" name="newRectangleShape" assertions="6" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newRevoluteJoint" name="newRevoluteJoint" assertions="3" time="0.017">
+		<testcase classname="newRevoluteJoint" name="newRevoluteJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newRopeJoint" name="newRopeJoint" assertions="3" time="0.018">
+		<testcase classname="newRopeJoint" name="newRopeJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newWeldJoint" name="newWeldJoint" assertions="3" time="0.019">
+		<testcase classname="newWeldJoint" name="newWeldJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newWheelJoint" name="newWheelJoint" assertions="3" time="0.016">
+		<testcase classname="newWheelJoint" name="newWheelJoint" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newWorld" name="newWorld" assertions="3" time="0.018">
+		<testcase classname="newWorld" name="newWorld" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="setMeter" name="setMeter" assertions="2" time="0.018">
+		<testcase classname="setMeter" name="setMeter" assertions="2" time="0.002">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.sound" tests="2" failures="0" skipped="2" time="0.072">
-		<testcase classname="Decoder" name="Decoder" assertions="0" time="0.016">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.sound" tests="4" failures="0" skipped="0" time="0.015">
+		<testcase classname="Decoder" name="Decoder" assertions="14" time="0.007">
 		</testcase>
 		</testcase>
-		<testcase classname="SoundData" name="SoundData" assertions="0" time="0.019">
-			<skipped message="test class needs writing" />
+		<testcase classname="SoundData" name="SoundData" assertions="20" time="0.003">
 		</testcase>
 		</testcase>
-		<testcase classname="newDecoder" name="newDecoder" assertions="3" time="0.020">
+		<testcase classname="newDecoder" name="newDecoder" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newSoundData" name="newSoundData" assertions="6" time="0.017">
+		<testcase classname="newSoundData" name="newSoundData" assertions="6" time="0.003">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.system" tests="6" failures="0" skipped="2" time="0.142">
-		<testcase classname="getClipboardText" name="getClipboardText" assertions="1" time="0.016">
+	<testsuite name="love.system" tests="6" failures="0" skipped="2" time="0.023">
+		<testcase classname="getClipboardText" name="getClipboardText" assertions="1" time="0.004">
 		</testcase>
 		</testcase>
-		<testcase classname="getOS" name="getOS" assertions="1" time="0.017">
+		<testcase classname="getOS" name="getOS" assertions="1" time="0.007">
 		</testcase>
 		</testcase>
-		<testcase classname="getPowerInfo" name="getPowerInfo" assertions="1" time="0.018">
+		<testcase classname="getPowerInfo" name="getPowerInfo" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getProcessorCount" name="getProcessorCount" assertions="1" time="0.018">
+		<testcase classname="getProcessorCount" name="getProcessorCount" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="hasBackgroundMusic" name="hasBackgroundMusic" assertions="1" time="0.019">
+		<testcase classname="hasBackgroundMusic" name="hasBackgroundMusic" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="openURL" name="openURL" assertions="0" time="0.018">
+		<testcase classname="openURL" name="openURL" assertions="0" time="0.002">
 			<skipped message="cant test this worked" />
 			<skipped message="cant test this worked" />
 		</testcase>
 		</testcase>
-		<testcase classname="setClipboardText" name="setClipboardText" assertions="1" time="0.018">
+		<testcase classname="setClipboardText" name="setClipboardText" assertions="1" time="0.003">
 		</testcase>
 		</testcase>
-		<testcase classname="vibrate" name="vibrate" assertions="0" time="0.018">
+		<testcase classname="vibrate" name="vibrate" assertions="0" time="0.002">
 			<skipped message="cant test this worked" />
 			<skipped message="cant test this worked" />
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.thread" tests="3" failures="0" skipped="2" time="0.088">
-		<testcase classname="Channel" name="Channel" assertions="0" time="0.015">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.thread" tests="5" failures="0" skipped="0" time="0.318">
+		<testcase classname="Channel" name="Channel" assertions="10" time="0.220">
 		</testcase>
 		</testcase>
-		<testcase classname="Thread" name="Thread" assertions="0" time="0.018">
-			<skipped message="test class needs writing" />
+		<testcase classname="Thread" name="Thread" assertions="7" time="0.092">
 		</testcase>
 		</testcase>
-		<testcase classname="getChannel" name="getChannel" assertions="3" time="0.018">
+		<testcase classname="getChannel" name="getChannel" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newChannel" name="newChannel" assertions="3" time="0.019">
+		<testcase classname="newChannel" name="newChannel" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="newThread" name="newThread" assertions="3" time="0.018">
+		<testcase classname="newThread" name="newThread" assertions="3" time="0.002">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.timer" tests="6" failures="0" skipped="0" time="2.086">
-		<testcase classname="getAverageDelta" name="getAverageDelta" assertions="1" time="0.015">
+	<testsuite name="love.timer" tests="6" failures="0" skipped="0" time="2.020">
+		<testcase classname="getAverageDelta" name="getAverageDelta" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getDelta" name="getDelta" assertions="1" time="0.017">
+		<testcase classname="getDelta" name="getDelta" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getFPS" name="getFPS" assertions="1" time="0.018">
+		<testcase classname="getFPS" name="getFPS" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getTime" name="getTime" assertions="1" time="1.008">
+		<testcase classname="getTime" name="getTime" assertions="1" time="1.003">
 		</testcase>
 		</testcase>
-		<testcase classname="sleep" name="sleep" assertions="1" time="1.011">
+		<testcase classname="sleep" name="sleep" assertions="1" time="1.006">
 		</testcase>
 		</testcase>
-		<testcase classname="step" name="step" assertions="1" time="0.018">
+		<testcase classname="step" name="step" assertions="1" time="0.004">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.video" tests="1" failures="0" skipped="1" time="0.031">
-		<testcase classname="VideoStream" name="VideoStream" assertions="0" time="0.014">
-			<skipped message="test class needs writing" />
+	<testsuite name="love.video" tests="2" failures="0" skipped="0" time="0.016">
+		<testcase classname="VideoStream" name="VideoStream" assertions="9" time="0.009">
 		</testcase>
 		</testcase>
-		<testcase classname="newVideoStream" name="newVideoStream" assertions="3" time="0.017">
+		<testcase classname="newVideoStream" name="newVideoStream" assertions="3" time="0.007">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
-	<testsuite name="love.window" tests="34" failures="0" skipped="2" time="5.273">
-		<testcase classname="close" name="close" assertions="2" time="0.035">
+	<testsuite name="love.window" tests="34" failures="0" skipped="2" time="5.954">
+		<testcase classname="close" name="close" assertions="2" time="0.054">
 		</testcase>
 		</testcase>
 		<testcase classname="fromPixels" name="fromPixels" assertions="1" time="0.002">
 		<testcase classname="fromPixels" name="fromPixels" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
 		<testcase classname="getDPIScale" name="getDPIScale" assertions="1" time="0.002">
 		<testcase classname="getDPIScale" name="getDPIScale" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getDesktopDimensions" name="getDesktopDimensions" assertions="2" time="0.016">
+		<testcase classname="getDesktopDimensions" name="getDesktopDimensions" assertions="2" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getDisplayCount" name="getDisplayCount" assertions="1" time="0.018">
+		<testcase classname="getDisplayCount" name="getDisplayCount" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="getDisplayName" name="getDisplayName" assertions="1" time="0.018">
+		<testcase classname="getDisplayName" name="getDisplayName" assertions="1" time="0.015">
 		</testcase>
 		</testcase>
-		<testcase classname="getDisplayOrientation" name="getDisplayOrientation" assertions="1" time="0.019">
+		<testcase classname="getDisplayOrientation" name="getDisplayOrientation" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getFullscreen" name="getFullscreen" assertions="2" time="1.346">
+		<testcase classname="getFullscreen" name="getFullscreen" assertions="2" time="1.340">
 		</testcase>
 		</testcase>
-		<testcase classname="getFullscreenModes" name="getFullscreenModes" assertions="1" time="0.017">
+		<testcase classname="getFullscreenModes" name="getFullscreenModes" assertions="1" time="0.009">
 		</testcase>
 		</testcase>
-		<testcase classname="getIcon" name="getIcon" assertions="2" time="0.016">
+		<testcase classname="getIcon" name="getIcon" assertions="2" time="0.019">
 		</testcase>
 		</testcase>
-		<testcase classname="getMode" name="getMode" assertions="3" time="0.017">
+		<testcase classname="getMode" name="getMode" assertions="3" time="0.014">
 		</testcase>
 		</testcase>
 		<testcase classname="getPosition" name="getPosition" assertions="2" time="0.017">
 		<testcase classname="getPosition" name="getPosition" assertions="2" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="getSafeArea" name="getSafeArea" assertions="4" time="0.017">
 		<testcase classname="getSafeArea" name="getSafeArea" assertions="4" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="getTitle" name="getTitle" assertions="1" time="0.017">
+		<testcase classname="getTitle" name="getTitle" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="getVSync" name="getVSync" assertions="3" time="0.018">
+		<testcase classname="getVSync" name="getVSync" assertions="1" time="0.017">
 		</testcase>
 		</testcase>
 		<testcase classname="hasFocus" name="hasFocus" assertions="1" time="0.018">
 		<testcase classname="hasFocus" name="hasFocus" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
 		<testcase classname="hasMouseFocus" name="hasMouseFocus" assertions="1" time="0.018">
 		<testcase classname="hasMouseFocus" name="hasMouseFocus" assertions="1" time="0.018">
 		</testcase>
 		</testcase>
-		<testcase classname="isDisplaySleepEnabled" name="isDisplaySleepEnabled" assertions="3" time="0.018">
+		<testcase classname="isDisplaySleepEnabled" name="isDisplaySleepEnabled" assertions="3" time="0.017">
 		</testcase>
 		</testcase>
-		<testcase classname="isMaximized" name="isMaximized" assertions="1" time="0.186">
+		<testcase classname="isMaximized" name="isMaximized" assertions="2" time="0.186">
 		</testcase>
 		</testcase>
-		<testcase classname="isMinimized" name="isMinimized" assertions="2" time="0.655">
+		<testcase classname="isMinimized" name="isMinimized" assertions="2" time="0.744">
 		</testcase>
 		</testcase>
-		<testcase classname="isOpen" name="isOpen" assertions="2" time="0.045">
+		<testcase classname="isOpen" name="isOpen" assertions="2" time="0.054">
 		</testcase>
 		</testcase>
-		<testcase classname="isVisible" name="isVisible" assertions="2" time="0.032">
+		<testcase classname="isVisible" name="isVisible" assertions="2" time="0.031">
 		</testcase>
 		</testcase>
-		<testcase classname="maximize" name="maximize" assertions="1" time="0.172">
+		<testcase classname="maximize" name="maximize" assertions="2" time="0.173">
 		</testcase>
 		</testcase>
-		<testcase classname="minimize" name="minimize" assertions="1" time="0.637">
+		<testcase classname="minimize" name="minimize" assertions="2" time="0.740">
 		</testcase>
 		</testcase>
 		<testcase classname="requestAttention" name="requestAttention" assertions="0" time="0.003">
 		<testcase classname="requestAttention" name="requestAttention" assertions="0" time="0.003">
 			<skipped message="cant test this worked" />
 			<skipped message="cant test this worked" />
 		</testcase>
 		</testcase>
-		<testcase classname="restore" name="restore" assertions="2" time="0.650">
+		<testcase classname="restore" name="restore" assertions="1" time="0.840">
 		</testcase>
 		</testcase>
-		<testcase classname="setDisplaySleepEnabled" name="setDisplaySleepEnabled" assertions="2" time="0.012">
+		<testcase classname="setDisplaySleepEnabled" name="setDisplaySleepEnabled" assertions="2" time="0.016">
 		</testcase>
 		</testcase>
-		<testcase classname="setFullscreen" name="setFullscreen" assertions="2" time="1.122">
+		<testcase classname="setFullscreen" name="setFullscreen" assertions="2" time="1.335">
 		</testcase>
 		</testcase>
-		<testcase classname="setIcon" name="setIcon" assertions="1" time="0.006">
+		<testcase classname="setIcon" name="setIcon" assertions="1" time="0.013">
 		</testcase>
 		</testcase>
-		<testcase classname="setMode" name="setMode" assertions="4" time="0.018">
+		<testcase classname="setMode" name="setMode" assertions="4" time="0.021">
 		</testcase>
 		</testcase>
-		<testcase classname="setPosition" name="setPosition" assertions="2" time="0.017">
+		<testcase classname="setPosition" name="setPosition" assertions="2" time="0.178">
 		</testcase>
 		</testcase>
-		<testcase classname="setTitle" name="setTitle" assertions="1" time="0.018">
+		<testcase classname="setTitle" name="setTitle" assertions="1" time="0.003">
 		</testcase>
 		</testcase>
-		<testcase classname="setVSync" name="setVSync" assertions="2" time="0.017">
+		<testcase classname="setVSync" name="setVSync" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="showMessageBox" name="showMessageBox" assertions="0" time="0.017">
+		<testcase classname="showMessageBox" name="showMessageBox" assertions="0" time="0.002">
 			<skipped message="cant test this worked" />
 			<skipped message="cant test this worked" />
 		</testcase>
 		</testcase>
-		<testcase classname="toPixels" name="toPixels" assertions="1" time="0.018">
+		<testcase classname="toPixels" name="toPixels" assertions="1" time="0.002">
 		</testcase>
 		</testcase>
-		<testcase classname="updateMode" name="updateMode" assertions="4" time="0.019">
+		<testcase classname="updateMode" name="updateMode" assertions="4" time="0.014">
 		</testcase>
 		</testcase>
 	</testsuite>
 	</testsuite>
 </testsuites>
 </testsuites>

+ 19 - 7
testing/readme.md

@@ -101,6 +101,8 @@ love.test.filesystem.read = function(test)
 end
 end
 ```
 ```
 
 
+Each test is run inside it's own coroutine - you can use `test:waitFrames(frames)` to pause the test for a small period if you need to check things that won't happen for a few seconds.
+
 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)
 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 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
 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
@@ -108,13 +110,23 @@ For sanity-checking, if it's currently not covered or it's not possible to test
 ---
 ---
 
 
 ## Todo 
 ## Todo 
-Modules with some small bits needed or needing sense checking:
-- **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.*.objects** - all objects tests still to be done
-- **love.graphics.setStencilTest** - deprecated, replaced by setStencilMode()
+Things still left to do:
+- [ ] physics.Body, physics.Contact, physics.Fixture,
+      physics.Joint, physics.Shape, physics.World
+- [ ] graphics.Canvas, graphics.Font, graphics.Image, graphics.Mesh, 
+      graphics.ParticleSystem, graphics.Quad, graphics.Shader, 
+      graphics.SpriteBatch, graphics.Text, graphics.Texture, graphics.Video
+- [ ] event.wait
+- [ ] graphics.present 
+- [ ] graphics.drawInstanced
+- [ ] graphics.setDepthMode (needs actual graphical comparison if possible)
+- [ ] graphics.setFrontFaceWinding (needs actual graphical comparison if possible)
+- [ ] graphics.setMeshCullMode (needs actual graphical comparison if possible)
+- [ ] @deprecated setStencilTest (use setStencilMode)
+- [ ] @deprecated physics methods (sasha changes)
+- [ ] check 12.0 wiki page for new methods
+- [ ] need a platform: format table somewhere for compressed formats (i.e. DXT not supported)
+- [ ] ideally graphics.isCompressed should have an example of all compressed files love can take
 
 
 ---
 ---
 
 

+ 488 - 1
testing/resources/alsoft.conf

@@ -1,4 +1,491 @@
+# OpenAL config file.
+#
+# Option blocks may appear multiple times, and duplicated options will take the
+# last value specified. Environment variables may be specified within option
+# values, and are automatically substituted when the config file is loaded.
+# Environment variable names may only contain alpha-numeric characters (a-z,
+# A-Z, 0-9) and underscores (_), and are prefixed with $. For example,
+# specifying "$HOME/file.ext" would typically result in something like
+# "/home/user/file.ext". To specify an actual "$" character, use "$$".
+#
+# Device-specific values may be specified by including the device name in the
+# block name, with "general" replaced by the device name. That is, general
+# options for the device "Name of Device" would be in the [Name of Device]
+# block, while ALSA options would be in the [alsa/Name of Device] block.
+# Options marked as "(global)" are not influenced by the device.
+#
+# The system-wide settings can be put in /etc/openal/alsoft.conf and user-
+# specific override settings in $HOME/.alsoftrc.
+# For Windows, these settings should go into $AppData\alsoft.ini
+#
+# Option and block names are case-senstive. The supplied values are only hints
+# and may not be honored (though generally it'll try to get as close as
+# possible). Note: options that are left unset may default to app- or system-
+# specified values. These are the current available settings:
+
+##
+## General stuff
+##
 [general]
 [general]
+
+## disable-cpu-exts: (global)
+#  Disables use of specialized methods that use specific CPU intrinsics.
+#  Certain methods may utilize CPU extensions for improved performance, and
+#  this option is useful for preventing some or all of those methods from being
+#  used. The available extensions are: sse, sse2, sse3, sse4.1, and neon.
+#  Specifying 'all' disables use of all such specialized methods.
+#disable-cpu-exts =
+
+## drivers: (global)
+#  Sets the backend driver list order, comma-seperated. Unknown backends and
+#  duplicated names are ignored. Unlisted backends won't be considered for use
+#  unless the list is ended with a comma (e.g. 'oss,' will try OSS first before
+#  other backends, while 'oss' will try OSS only). Backends prepended with -
+#  won't be considered for use (e.g. '-oss,' will try all available backends
+#  except OSS). An empty list means to try all backends.
 drivers = wave
 drivers = wave
+
+## channels:
+#  Sets the output channel configuration. If left unspecified, one will try to
+#  be detected from the system, and defaulting to stereo. The available values
+#  are: mono, stereo, quad, surround51, surround51rear, surround61, surround71,
+#  ambi1, ambi2, ambi3. Note that the ambi* configurations provide ambisonic
+#  channels of the given order (using ACN ordering and SN3D normalization by
+#  default), which need to be decoded to play correctly on speakers.
+#channels =
+
+## sample-type:
+#  Sets the output sample type. Currently, all mixing is done with 32-bit float
+#  and converted to the output sample type as needed. Available values are:
+#  int8    - signed 8-bit int
+#  uint8   - unsigned 8-bit int
+#  int16   - signed 16-bit int
+#  uint16  - unsigned 16-bit int
+#  int32   - signed 32-bit int
+#  uint32  - unsigned 32-bit int
+#  float32 - 32-bit float
+#sample-type = float32
+
+## frequency:
+#  Sets the output frequency. If left unspecified it will try to detect a
+#  default from the system, otherwise it will default to 44100.
+#frequency =
+
+## period_size:
+#  Sets the update period size, in frames. This is the number of frames needed
+#  for each mixing update. Acceptable values range between 64 and 8192.
+#period_size = 1024
+
+## periods:
+#  Sets the number of update periods. Higher values create a larger mix ahead,
+#  which helps protect against skips when the CPU is under load, but increases
+#  the delay between a sound getting mixed and being heard. Acceptable values
+#  range between 2 and 16.
+#periods = 3
+
+## stereo-mode:
+#  Specifies if stereo output is treated as being headphones or speakers. With
+#  headphones, HRTF or crossfeed filters may be used for better audio quality.
+#  Valid settings are auto, speakers, and headphones.
+#stereo-mode = auto
+
+## stereo-encoding:
+#  Specifies the encoding method for non-HRTF stereo output. 'panpot' (default)
+#  uses standard amplitude panning (aka pair-wise, stereo pair, etc) between
+#  -30 and +30 degrees, while 'uhj' creates stereo-compatible two-channel UHJ
+#  output, which encodes some surround sound information into stereo output
+#  that can be decoded with a surround sound receiver. If crossfeed filters are
+#  used, UHJ is disabled.
+#stereo-encoding = panpot
+
+## ambi-format:
+#  Specifies the channel order and normalization for the "ambi*" set of channel
+#  configurations. Valid settings are: fuma, acn+sn3d, acn+n3d
+#ambi-format = acn+sn3d
+
+## hrtf:
+#  Controls HRTF processing. These filters provide better spatialization of
+#  sounds while using headphones, but do require a bit more CPU power. The
+#  default filters will only work with 44100hz or 48000hz stereo output. While
+#  HRTF is used, the cf_level option is ignored. Setting this to auto (default)
+#  will allow HRTF to be used when headphones are detected or the app requests
+#  it, while setting true or false will forcefully enable or disable HRTF
+#  respectively.
+#hrtf = auto
+
+## default-hrtf:
+#  Specifies the default HRTF to use. When multiple HRTFs are available, this
+#  determines the preferred one to use if none are specifically requested. Note
+#  that this is the enumerated HRTF name, not necessarily the filename.
+#default-hrtf =
+
+## hrtf-paths:
+#  Specifies a comma-separated list of paths containing HRTF data sets. The
+#  format of the files are described in docs/hrtf.txt. The files within the
+#  directories must have the .mhr file extension to be recognized. By default,
+#  OS-dependent data paths will be used. They will also be used if the list
+#  ends with a comma. On Windows this is:
+#  $AppData\openal\hrtf
+#  And on other systems, it's (in order):
+#  $XDG_DATA_HOME/openal/hrtf  (defaults to $HOME/.local/share/openal/hrtf)
+#  $XDG_DATA_DIRS/openal/hrtf  (defaults to /usr/local/share/openal/hrtf and
+#                               /usr/share/openal/hrtf)
+#hrtf-paths =
+
+## cf_level:
+#  Sets the crossfeed level for stereo output. Valid values are:
+#  0 - No crossfeed
+#  1 - Low crossfeed
+#  2 - Middle crossfeed
+#  3 - High crossfeed (virtual speakers are closer to itself)
+#  4 - Low easy crossfeed
+#  5 - Middle easy crossfeed
+#  6 - High easy crossfeed
+#  Users of headphones may want to try various settings. Has no effect on non-
+#  stereo modes.
+#cf_level = 0
+
+## resampler: (global)
+#  Selects the resampler used when mixing sources. Valid values are:
+#  point - nearest sample, no interpolation
+#  linear - extrapolates samples using a linear slope between samples
+#  cubic - extrapolates samples using a Catmull-Rom spline
+#  bsinc12 - extrapolates samples using a band-limited Sinc filter (varying
+#            between 12 and 24 points, with anti-aliasing)
+#  bsinc24 - extrapolates samples using a band-limited Sinc filter (varying
+#            between 24 and 48 points, with anti-aliasing)
+#resampler = linear
+
+## rt-prio: (global)
+#  Sets real-time priority for the mixing thread. Not all drivers may use this
+#  (eg. PortAudio) as they already control the priority of the mixing thread.
+#  0 and negative values will disable it. Note that this may constitute a
+#  security risk since a real-time priority thread can indefinitely block
+#  normal-priority threads if it fails to wait. As such, the default is
+#  disabled.
+#rt-prio = 0
+
+## sources:
+#  Sets the maximum number of allocatable sources. Lower values may help for
+#  systems with apps that try to play more sounds than the CPU can handle.
+#sources = 256
+
+## slots:
+#  Sets the maximum number of Auxiliary Effect Slots an app can create. A slot
+#  can use a non-negligible amount of CPU time if an effect is set on it even
+#  if no sources are feeding it, so this may help when apps use more than the
+#  system can handle.
+#slots = 64
+
+## sends:
+#  Limits the number of auxiliary sends allowed per source. Setting this higher
+#  than the default has no effect.
+#sends = 16
+
+## front-stablizer:
+#  Applies filters to "stablize" front sound imaging. A psychoacoustic method
+#  is used to generate a front-center channel signal from the front-left and
+#  front-right channels, improving the front response by reducing the combing
+#  artifacts and phase errors. Consequently, it will only work with channel
+#  configurations that include front-left, front-right, and front-center.
+#front-stablizer = false
+
+## output-limiter:
+#  Applies a gain limiter on the final mixed output. This reduces the volume
+#  when the output samples would otherwise clamp, avoiding excessive clipping
+#  noise.
+#output-limiter = true
+
+## dither:
+#  Applies dithering on the final mix, for 8- and 16-bit output by default.
+#  This replaces the distortion created by nearest-value quantization with low-
+#  level whitenoise.
+#dither = true
+
+## dither-depth:
+#  Quantization bit-depth for dithered output. A value of 0 (or less) will
+#  match the output sample depth. For int32, uint32, and float32 output, 0 will
+#  disable dithering because they're at or beyond the rendered precision. The
+#  maximum dither depth is 24.
+#dither-depth = 0
+
+## volume-adjust:
+#  A global volume adjustment for source output, expressed in decibels. The
+#  value is logarithmic, so +6 will be a scale of (approximately) 2x, +12 will
+#  be a scale of 4x, etc. Similarly, -6 will be x1/2, and -12 is about x1/4. A
+#  value of 0 means no change.
+#volume-adjust = 0
+
+## excludefx: (global)
+#  Sets which effects to exclude, preventing apps from using them. This can
+#  help for apps that try to use effects which are too CPU intensive for the
+#  system to handle. Available effects are: eaxreverb,reverb,autowah,chorus,
+#  compressor,distortion,echo,equalizer,flanger,modulator,dedicated,pshifter,
+#  fshifter
+#excludefx =
+
+## default-reverb: (global)
+#  A reverb preset that applies by default to all sources on send 0
+#  (applications that set their own slots on send 0 will override this).
+#  Available presets are: None, Generic, PaddedCell, Room, Bathroom,
+#  Livingroom, Stoneroom, Auditorium, ConcertHall, Cave, Arena, Hangar,
+#  CarpetedHallway, Hallway, StoneCorridor, Alley, Forest, City, Moutains,
+#  Quarry, Plain, ParkingLot, SewerPipe, Underwater, Drugged, Dizzy, Psychotic.
+#default-reverb =
+
+## trap-alc-error: (global)
+#  Generates a SIGTRAP signal when an ALC device error is generated, on systems
+#  that support it. This helps when debugging, while trying to find the cause
+#  of a device error. On Windows, a breakpoint exception is generated.
+#trap-alc-error = false
+
+## trap-al-error: (global)
+#  Generates a SIGTRAP signal when an AL context error is generated, on systems
+#  that support it. This helps when debugging, while trying to find the cause
+#  of a context error. On Windows, a breakpoint exception is generated.
+#trap-al-error = false
+
+##
+## Ambisonic decoder stuff
+##
+[decoder]
+
+## hq-mode:
+#  Enables a high-quality ambisonic decoder. This mode is capable of frequency-
+#  dependent processing, creating a better reproduction of 3D sound rendering
+#  over surround sound speakers. Enabling this also requires specifying decoder
+#  configuration files for the appropriate speaker configuration you intend to
+#  use (see the quad, surround51, etc options below). Currently, up to third-
+#  order decoding is supported.
+hq-mode = false
+
+## distance-comp:
+#  Enables compensation for the speakers' relative distances to the listener.
+#  This applies the necessary delays and attenuation to make the speakers
+#  behave as though they are all equidistant, which is important for proper
+#  playback of 3D sound rendering. Requires the proper distances to be
+#  specified in the decoder configuration file.
+distance-comp = true
+
+## nfc:
+#  Enables near-field control filters. This simulates and compensates for low-
+#  frequency effects caused by the curvature of nearby sound-waves, which
+#  creates a more realistic perception of sound distance. Note that the effect
+#  may be stronger or weaker than intended if the application doesn't use or
+#  specify an appropriate unit scale, or if incorrect speaker distances are set
+#  in the decoder configuration file. Requires hq-mode to be enabled.
+nfc = true
+
+## nfc-ref-delay
+#  Specifies the reference delay value for ambisonic output. When channels is
+#  set to one of the ambi* formats, this option enables NFC-HOA output with the
+#  specified Reference Delay parameter. The specified value can then be shared
+#  with an appropriate NFC-HOA decoder to reproduce correct near-field effects.
+#  Keep in mind that despite being designed for higher-order ambisonics, this
+#  applies to first-order output all the same. When left unset, normal output
+#  is created with no near-field simulation.
+nfc-ref-delay =
+
+## quad:
+#  Decoder configuration file for Quadraphonic channel output. See
+#  docs/ambdec.txt for a description of the file format.
+quad =
+
+## surround51:
+#  Decoder configuration file for 5.1 Surround (Side and Rear) channel output.
+#  See docs/ambdec.txt for a description of the file format.
+surround51 =
+
+## surround61:
+#  Decoder configuration file for 6.1 Surround channel output. See
+#  docs/ambdec.txt for a description of the file format.
+surround61 =
+
+## surround71:
+#  Decoder configuration file for 7.1 Surround channel output. See
+#  docs/ambdec.txt for a description of the file format. Note: This can be used
+#  to enable 3D7.1 with the appropriate configuration and speaker placement,
+#  see docs/3D7.1.txt.
+surround71 =
+
+##
+## Reverb effect stuff (includes EAX reverb)
+##
+[reverb]
+
+## boost: (global)
+#  A global amplification for reverb output, expressed in decibels. The value
+#  is logarithmic, so +6 will be a scale of (approximately) 2x, +12 will be a
+#  scale of 4x, etc. Similarly, -6 will be about half, and -12 about 1/4th. A
+#  value of 0 means no change.
+#boost = 0
+
+##
+## PulseAudio backend stuff
+##
+[pulse]
+
+## spawn-server: (global)
+#  Attempts to autospawn a PulseAudio server whenever needed (initializing the
+#  backend, enumerating devices, etc). Setting autospawn to false in Pulse's
+#  client.conf will still prevent autospawning even if this is set to true.
+#spawn-server = true
+
+## allow-moves: (global)
+#  Allows PulseAudio to move active streams to different devices. Note that the
+#  device specifier (seen by applications) will not be updated when this
+#  occurs, and neither will the AL device configuration (sample rate, format,
+#  etc).
+#allow-moves = false
+
+## fix-rate:
+#  Specifies whether to match the playback stream's sample rate to the device's
+#  sample rate. Enabling this forces OpenAL Soft to mix sources and effects
+#  directly to the actual output rate, avoiding a second resample pass by the
+#  PulseAudio server.
+#fix-rate = false
+
+##
+## ALSA backend stuff
+##
+[alsa]
+
+## device: (global)
+#  Sets the device name for the default playback device.
+#device = default
+
+## device-prefix: (global)
+#  Sets the prefix used by the discovered (non-default) playback devices. This
+#  will be appended with "CARD=c,DEV=d", where c is the card id and d is the
+#  device index for the requested device name.
+#device-prefix = plughw:
+
+## device-prefix-*: (global)
+#  Card- and device-specific prefixes may be used to override the device-prefix
+#  option. The option may specify the card id (eg, device-prefix-NVidia), or
+#  the card id and device index (eg, device-prefix-NVidia-0). The card id is
+#  case-sensitive.
+#device-prefix- =
+
+## capture: (global)
+#  Sets the device name for the default capture device.
+#capture = default
+
+## capture-prefix: (global)
+#  Sets the prefix used by the discovered (non-default) capture devices. This
+#  will be appended with "CARD=c,DEV=d", where c is the card id and d is the
+#  device number for the requested device name.
+#capture-prefix = plughw:
+
+## capture-prefix-*: (global)
+#  Card- and device-specific prefixes may be used to override the
+#  capture-prefix option. The option may specify the card id (eg,
+#  capture-prefix-NVidia), or the card id and device index (eg,
+#  capture-prefix-NVidia-0). The card id is case-sensitive.
+#capture-prefix- =
+
+## mmap:
+#  Sets whether to try using mmap mode (helps reduce latencies and CPU
+#  consumption). If mmap isn't available, it will automatically fall back to
+#  non-mmap mode. True, yes, on, and non-0 values will attempt to use mmap. 0
+#  and anything else will force mmap off.
+#mmap = true
+
+## allow-resampler:
+#  Specifies whether to allow ALSA's built-in resampler. Enabling this will
+#  allow the playback device to be set to a different sample rate than the
+#  actual output, causing ALSA to apply its own resampling pass after OpenAL
+#  Soft resamples and mixes the sources and effects for output.
+#allow-resampler = false
+
+##
+## OSS backend stuff
+##
+[oss]
+
+## device: (global)
+#  Sets the device name for OSS output.
+#device = /dev/dsp
+
+## capture: (global)
+#  Sets the device name for OSS capture.
+#capture = /dev/dsp
+
+##
+## Solaris backend stuff
+##
+[solaris]
+
+## device: (global)
+#  Sets the device name for Solaris output.
+#device = /dev/audio
+
+##
+## QSA backend stuff
+##
+[qsa]
+
+##
+## JACK backend stuff
+##
+[jack]
+
+## spawn-server: (global)
+#  Attempts to autospawn a JACK server whenever needed (initializing the
+#  backend, opening devices, etc).
+#spawn-server = false
+
+## buffer-size:
+#  Sets the update buffer size, in samples, that the backend will keep buffered
+#  to handle the server's real-time processing requests. This value must be a
+#  power of 2, or else it will be rounded up to the next power of 2. If it is
+#  less than JACK's buffer update size, it will be clamped. This option may
+#  be useful in case the server's update size is too small and doesn't give the
+#  mixer time to keep enough audio available for the processing requests.
+#buffer-size = 0
+
+##
+## WASAPI backend stuff
+##
+[wasapi]
+
+##
+## DirectSound backend stuff
+##
+[dsound]
+
+##
+## Windows Multimedia backend stuff
+##
+[winmm]
+
+##
+## PortAudio backend stuff
+##
+[port]
+
+## device: (global)
+#  Sets the device index for output. Negative values will use the default as
+#  given by PortAudio itself.
+#device = -1
+
+## capture: (global)
+#  Sets the device index for capture. Negative values will use the default as
+#  given by PortAudio itself.
+#capture = -1
+
+##
+## Wave File Writer stuff
+##
 [wave]
 [wave]
-file = output.wav
+
+## file: (global)
+#  Sets the filename of the wave file to write to. An empty name prevents the
+#  backend from opening, even when explicitly requested.
+#  THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION!
+file = output.wav
+
+## bformat: (global)
+#  Creates AMB format files using first-order ambisonics instead of a standard
+#  single- or multi-channel .wav file.
+#bformat = false

+ 25 - 29
testing/tests/audio.lua

@@ -15,36 +15,32 @@ love.test.audio.RecordingDevice = function(test)
   if #devices == 0 then
   if #devices == 0 then
     return test:skipTest('cant test this works: no recording devices found')
     return test:skipTest('cant test this works: no recording devices found')
   end
   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)
+  -- check object created and basics
+  local device = devices[1]
+  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
+  -- @TODO needs delay for VMs
+  local startrecording = device:start(32000, 4000, 16, 1)
+  test:waitFrames(120)
+  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')
+  local recording = device:stop()
+  test:waitFrames(120)
   -- after recording 
   -- 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
+  test:assertEquals(false, device:isRecording(), 'check not recording')
+  test:assertEquals(nil, device:getData(), 'using stop should clear buffer')
+  test:assertObject(recording)
 end
 end
 
 
 
 

+ 47 - 8
testing/tests/graphics.lua

@@ -10,7 +10,49 @@
 
 
 -- Canvas (love.graphics.newCanvas)
 -- Canvas (love.graphics.newCanvas)
 love.test.graphics.Canvas = function(test)
 love.test.graphics.Canvas = function(test)
-  test:skipTest('test class needs writing')
+  -- create canvas
+  local canvas = love.graphics.newCanvas(32, 32, {
+
+  })
+  test:assertObject(canvas)
+  -- check basic properties
+  test:assertNotNil(canvas:getMSAA())
+  test:assertEquals('none', canvas:getMipmapMode(), 'check default mipmap')
+  --[[
+
+    Texture:getDPIScale check not nil
+    Texture:getDepth check >= 0
+    Texture:getDimensions	w, h 
+
+    Texture:getFormat (list of vals)
+    Texture:getHeight h
+    Texture:getLayerCount >= 0
+    Texture:getMipmapCount >= 1
+    Texture:getPixelDimensions w, h + dpi
+    Texture:getPixelHeight h + dpi
+    Texture:getPixelWidth w + dpi
+    Texture:getTextureType teture types (4 types)
+    Texture:getWidth w
+    Texture:isReadable true unless stencil/depth pixel formats 
+
+    Texture:getWrap
+    Texture:setWrap horiz, vert, depth
+
+    Texture:getDepthSampleMode
+    Texture:setDepthSampleMode compare (list of vals)
+
+    Texture:getFilter
+    Texture:setFilter min, mag, anisotrop
+
+    Texture:getMipmapFilter
+    Texture:setMipmapFilter mode, sharpness
+  ]]
+  -- check rendering
+  canvas:renderTo(function()
+  
+  end)
+  local data = love.graphics.readbackTexture(canvas, {16, 0, 0, 0, 16, 16})
+  -- check some pixels
 end
 end
 
 
 
 
@@ -489,14 +531,11 @@ end
 
 
 -- love.graphics.captureScreenshot
 -- love.graphics.captureScreenshot
 love.test.graphics.captureScreenshot = function(test)
 love.test.graphics.captureScreenshot = function(test)
-  if test:isDelayed() == false then
-    love.graphics.captureScreenshot('example-screenshot.png')
-    test:setDelay(10)
+  love.graphics.captureScreenshot('example-screenshot.png')
+  test:waitFrames(10)
   -- need to wait until end of the frame for the screenshot
   -- need to wait until end of the frame for the screenshot
-  else
-    test:assertNotNil(love.filesystem.openFile('example-screenshot.png', 'r'))
-    love.filesystem.remove('example-screenshot.png')
-  end
+  test:assertNotNil(love.filesystem.openFile('example-screenshot.png', 'r'))
+  love.filesystem.remove('example-screenshot.png')
 end
 end
 
 
 
 

+ 41 - 63
testing/tests/window.lua

@@ -168,31 +168,25 @@ end
 
 
 -- love.window.isMaximized
 -- love.window.isMaximized
 love.test.window.isMaximized = function(test)
 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
-    -- on MACOS maximize wont get recognised immedietely so wait a few frames
-    test:assertEquals(true, love.window.isMaximized(), 'check window now maximized')
-    love.window.restore()
-  end
+  test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
+  love.window.maximize()
+  test:waitFrames(10)
+  -- on MACOS maximize wont get recognised immedietely so wait a few frames
+  test:assertEquals(true, love.window.isMaximized(), 'check window now maximized')
+  love.window.restore()
 end
 end
 
 
 
 
 -- love.window.isMinimized
 -- love.window.isMinimized
 love.test.window.isMinimized = function(test)
 love.test.window.isMinimized = function(test)
-  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
+  -- check not minimized to start
+  test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
+  -- try to minimize
+  love.window.minimize()
+  test:waitFrames(10)
+  -- 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
 
 
 
 
@@ -220,31 +214,25 @@ end
 
 
 -- love.window.maximize
 -- love.window.maximize
 love.test.window.maximize = function(test)
 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)
-  else
-    -- on macos we need to wait a few frames
-    test:assertEquals(true, love.window.isMaximized(), 'check window maximized')
-    love.window.restore()
-  end
+  test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
+  -- check maximizing is set
+  love.window.maximize()
+  test:waitFrames(10)
+  -- on macos we need to wait a few frames
+  test:assertEquals(true, love.window.isMaximized(), 'check window maximized')
+  love.window.restore()
 end
 end
 
 
 
 
 -- love.window.minimize
 -- love.window.minimize
 love.test.window.minimize = function(test)
 love.test.window.minimize = function(test)
-  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
+  test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
+  -- check minimizing is set
+  love.window.minimize()
+  test:waitFrames(10)
+  -- on linux we need to wait a few frames
+  test:assertEquals(true, love.window.isMinimized(), 'check window maximized')
+  love.window.restore()
 end
 end
 
 
 
 
@@ -256,20 +244,13 @@ end
 
 
 -- love.window.restore
 -- love.window.restore
 love.test.window.restore = function(test)
 love.test.window.restore = function(test)
-
-  -- 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
-
+  -- check minimized to start
+  love.window.minimize()
+  test:waitFrames(10)
+  love.window.restore()
+  test:waitFrames(10)
+  -- check restoring the state of the window
+  test:assertEquals(false, love.window.isMinimized(), 'check window restored')
 end
 end
 
 
 
 
@@ -327,15 +308,12 @@ end
 
 
 -- love.window.setPosition
 -- love.window.setPosition
 love.test.window.setPosition = function(test)
 love.test.window.setPosition = function(test)
-  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
+  -- check position is returned
+  love.window.setPosition(100, 100, 1)
+  test:waitFrames(10)
+  local x, y, _ = love.window.getPosition()
+  test:assertEquals(100, x, 'check position x')
+  test:assertEquals(100, y, 'check position y')
 end
 end
 
 
 
 

+ 0 - 26
testing/todo.md

@@ -1,26 +0,0 @@
-`/Applications/love_12.app/Contents/MacOS/love ./testing`
-
-## 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)
-
-## 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

Some files were not shown because too many files changed in this diff