Browse Source

review changes

- spaced out object class tests and added more defined comment groups

- changed reusing vars in case it causes unexpected asserts in future

- fixed some shape:point test having wrong params

- added assertTrue + assertFalse for basic checks

- used assertRange more for some of the physics + audio tests
ell 1 year ago
parent
commit
f846d4ab91

+ 52 - 18
testing/classes/TestMethod.lua

@@ -71,6 +71,58 @@ TestMethod = {
   end,
 
 
+  -- @method - TestMethod:assertTrue()
+  -- @desc - used to assert a value is true
+  -- @param {any} value - value to test
+  -- @param {string} label - label for this test to use in exports
+  -- @return {nil}
+  assertTrue = function(self, value, label)
+    self.count = self.count + 1
+    table.insert(self.asserts, {
+      key = 'assert ' .. tostring(self.count),
+      passed = value == true,
+      message = 'expected \'true\' got \'' .. 
+        tostring(value) .. '\'',
+      test = label or 'no label given'
+    })
+  end,
+
+
+  -- @method - TestMethod:assertFalse()
+  -- @desc - used to assert a value is false
+  -- @param {any} value - value to test
+  -- @param {string} label - label for this test to use in exports
+  -- @return {nil}
+  assertFalse = function(self, value, label)
+    self.count = self.count + 1
+    table.insert(self.asserts, {
+      key = 'assert ' .. tostring(self.count),
+      passed = value == false,
+      message = 'expected \'false\' got \'' .. 
+        tostring(value) .. '\'',
+      test = label or 'no label given'
+    })
+  end,
+
+
+  -- @method - TestMethod:assertNotEquals()
+  -- @desc - used to assert two values are not equal
+  -- @param {any} expected - expected value of the test
+  -- @param {any} actual - actual value of the test
+  -- @param {string} label - label for this test to use in exports
+  -- @return {nil}
+  assertNotEquals = function(self, expected, actual, label)
+    self.count = self.count + 1
+    table.insert(self.asserts, {
+      key = 'assert ' .. tostring(self.count),
+      passed = expected ~= actual,
+      message = 'avoiding \'' .. tostring(expected) .. '\' got \'' ..
+        tostring(actual) .. '\'',
+      test = label or 'no label given'
+    })
+  end,
+
+
   -- @method - TestMethod:assertPixels()
   -- @desc - checks a list of coloured pixels agaisnt given imgdata
   -- @param {ImageData} imgdata - image data to check
@@ -103,24 +155,6 @@ TestMethod = {
   end,
 
 
-  -- @method - TestMethod:assertNotEquals()
-  -- @desc - used to assert two values are not equal
-  -- @param {any} expected - expected value of the test
-  -- @param {any} actual - actual value of the test
-  -- @param {string} label - label for this test to use in exports
-  -- @return {nil}
-  assertNotEquals = function(self, expected, actual, label)
-    self.count = self.count + 1
-    table.insert(self.asserts, {
-      key = 'assert ' .. tostring(self.count),
-      passed = expected ~= actual,
-      message = 'avoiding \'' .. tostring(expected) .. '\' got \'' ..
-        tostring(actual) .. '\'',
-      test = label or 'no label given'
-    })
-  end,
-
-
   -- @method - TestMethod:assertRange()
   -- @desc - used to check a value is within an expected range
   -- @param {number} actual - actual value of the test

+ 2 - 0
testing/readme.md

@@ -78,6 +78,8 @@ When you run the tests, a single TestSuite object is created which handles the p
 Each module has a TestModule object created, and each test method has a TestMethod object created which keeps track of assertions for that method. You can currently do the following assertions:
 - **assertNotNil**(value)
 - **assertEquals**(expected, actual, label)
+- **assertTrue**(value, label)
+- **assertFalse**(value, label)
 - **assertNotEquals**(expected, actual, label)
 - **assertRange**(actual, min, max, label)
 - **assertMatch**({option1, option2, option3 ...}, actual, label) 

+ 57 - 25
testing/tests/audio.lua

@@ -10,137 +10,167 @@
 
 -- RecordingDevice (love.audio.getRecordingDevices)
 love.test.audio.RecordingDevice = function(test)
+
+  -- skip recording device on runners, they cant emulate it
   if GITHUB_RUNNER == true then
     return test:skipTest('cant emulate recording devices in CI')
   end
+
   -- check devices first
   local devices = love.audio.getRecordingDevices()
   if #devices == 0 then
     return test:skipTest('cant test this works: no recording devices found')
   end
+
   -- 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')
+  test:assertFalse(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(10)
-  test:assertEquals(true, startrecording, 'check recording started')
-  test:assertEquals(true, device:isRecording(), 'check now recording')
+  test:assertTrue(startrecording, 'check recording started')
+  test:assertTrue(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(10)
+
   -- after recording 
-  test:assertEquals(false, device:isRecording(), 'check not recording')
+  test:assertFalse(device:isRecording(), 'check not recording')
   test:assertEquals(nil, device:getData(), 'using stop should clear buffer')
   test:assertObject(recording)
+
 end
 
 
 -- Source (love.audio.newSource)
 love.test.audio.Source = function(test)
+
   -- create stereo source
   local stereo = love.audio.newSource('resources/click.ogg', 'static')
   test:assertObject(stereo)
+
   -- check stereo props
   test:assertEquals(2, stereo:getChannelCount(), 'check stereo src')
-  test:assertEquals(66, math.floor(stereo:getDuration("seconds")*1000), 'check stereo seconds')
+  test:assertRange(stereo:getDuration("seconds"), 0, 0.1, 'check stereo seconds')
   test:assertNotNil(stereo:getFreeBufferCount())
   test:assertEquals('static', stereo:getType(), 'check stereo type')
+
   -- check cloning a stereo
   local clone = stereo:clone()
   test:assertEquals(2, clone:getChannelCount(), 'check clone stereo src')
-  test:assertEquals(66, math.floor(clone:getDuration("seconds")*1000), 'check clone stereo seconds')
+  test:assertRange(clone:getDuration("seconds"), 0, 0.1, 'check clone stereo seconds')
   test:assertNotNil(clone:getFreeBufferCount())
   test:assertEquals('static', clone:getType(), 'check cloned stereo type')
+
   -- mess with stereo playing
-  test:assertEquals(false, stereo:isPlaying(), 'check not playing')
+  test:assertFalse(stereo:isPlaying(), 'check not playing')
   stereo:setLooping(true)
   stereo:play()
-  test:assertEquals(true, stereo:isPlaying(), 'check now playing')
-  test:assertEquals(true, stereo:isLooping(), 'check now playing')
+  test:assertTrue(stereo:isPlaying(), 'check now playing')
+  test:assertTrue(stereo:isLooping(), 'check now playing')
   stereo:pause()
   stereo:seek(0.01, 'seconds')
   test:assertEquals(0.01, stereo:tell('seconds'), 'check seek/tell')
   stereo:stop()
-  test:assertEquals(false, stereo:isPlaying(), 'check stopped playing')
+  test:assertFalse(stereo:isPlaying(), 'check stopped playing')
+
   -- check volume limits
   stereo:setVolumeLimits(0.1, 0.5)
   local min, max = stereo:getVolumeLimits()
-  test:assertEquals(1, math.floor(min*10), 'check min limit')
-  test:assertEquals(5, math.floor(max*10), 'check max limit')
-  -- @NOTE the following works as setVolumeLimits is used with set volume
-  -- as the BASE and then applying directional, rather than being a clamp
+  test:assertRange(min, 0.1, 0.2, 'check min limit')
+  test:assertRange(max, 0.5, 0.6, 'check max limit')
+
+  -- check setting volume
   stereo:setVolume(1)
   test:assertEquals(1, stereo:getVolume(), 'check set volume')
   stereo:setVolume(0)
   test:assertEquals(0, stereo:getVolume(), 'check set volume')
+
   -- change some get/set props that can apply to stereo
   stereo:setPitch(2)
   test:assertEquals(2, stereo:getPitch(), 'check pitch change')
+
   -- create mono source
   local mono = love.audio.newSource('resources/clickmono.ogg', 'stream')
   test:assertObject(mono)
   test:assertEquals(1, mono:getChannelCount(), 'check mono src')
   test:assertEquals(2927, mono:getDuration("samples"), 'check mono seconds')
   test:assertEquals('stream', mono:getType(), 'check mono type')
-  -- check the basic get/set properties
+
+  -- air absorption
   test:assertEquals(0, mono:getAirAbsorption(), 'get air absorption')
   mono:setAirAbsorption(1)
   test:assertEquals(1, mono:getAirAbsorption(), 'set air absorption')
+
+  -- cone
   mono:setCone(0, 90*(math.pi/180), 1)
   local ia, oa, ov = mono:getCone()
   test:assertEquals(0, ia, 'check cone ia')
   test:assertEquals(math.floor(9000*(math.pi/180)), math.floor(oa*100), 'check cone oa')
   test:assertEquals(1, ov, 'check cone ov')
+
+  -- direction
   mono:setDirection(3, 1, -1)
   local x, y, z = mono:getDirection()
   test:assertEquals(3, x, 'check direction x')
   test:assertEquals(1, y, 'check direction y')
   test:assertEquals(-1, z, 'check direction z')
+
+  -- relative
   mono:setRelative(true)
-  test:assertEquals(true, mono:isRelative(), 'check set relative')
+  test:assertTrue(mono:isRelative(), 'check set relative')
+
+  -- position
   mono:setPosition(1, 2, 3)
   x, y, z = mono:getPosition()
   test:assertEquals(x, 1, 'check pos x')
   test:assertEquals(y, 2, 'check pos y')
   test:assertEquals(z, 3, 'check pos z')
+
+  -- velocity
   mono:setVelocity(1, 3, 4)
   x, y, z = mono:getVelocity()
   test:assertEquals(x, 1, 'check velocity x')
   test:assertEquals(y, 3, 'check velocity x')
   test:assertEquals(z, 4, 'check velocity x')
+
+  -- rolloff
   mono:setRolloff(1)
   test:assertEquals(1, mono:getRolloff(), 'check rolloff set')
+
   -- create queue source
   local queue = love.audio.newQueueableSource(44100, 16, 1, 3)
   local sdata = love.sound.newSoundData(1024, 44100, 16, 1)
   test:assertObject(queue)
   local run = queue:queue(sdata)
-  test:assertEquals(true, run, 'check queued sound')
+  test:assertTrue(run, 'check queued sound')
   queue:stop()
+
   -- check making a filer
   local setfilter = stereo:setFilter({
     type = 'lowpass',
     volume = 0.5,
     highgain = 0.3
   })
-  test:assertEquals(true, setfilter, 'check filter applied')
+  test:assertTrue(setfilter, 'check filter applied')
   local filter = stereo:getFilter()
   test:assertEquals('lowpass', filter.type, 'check filter type')
   test:assertEquals(0.5, filter.volume, 'check filter volume')
-  test:assertEquals(3, math.floor(filter.highgain*10), 'check filter highgain')
+  test:assertRange(filter.highgain, 0.3, 0.4, 'check filter highgain')
   test:assertEquals(nil, filter.lowgain, 'check filter lowgain')
+
   -- add an effect
   local effsource = love.audio.newSource('resources/click.ogg', 'static')
   love.audio.setEffect('testeffect', {
@@ -152,10 +182,12 @@ love.test.audio.Source = function(test)
     volume = 0.3,
     lowgain = 0.1
   })
+
   -- both these fail on 12 using stereo or mono, no err
-  test:assertEquals(true, seteffect, 'check effect was applied')
+  test:assertTrue(seteffect, 'check effect was applied')
   local filtersettings = effsource:getEffect('effectthatdoesntexist', {})
   test:assertNotNil(filtersettings)
+
 end
 
 
@@ -339,7 +371,7 @@ love.test.audio.play = function(test)
   -- check playing source is detected
   local source = love.audio.newSource('resources/click.ogg', 'static')
   love.audio.play(source)
-  test:assertEquals(true, source:isPlaying(), 'check something playing')
+  test:assertTrue(source:isPlaying(), 'check something playing')
   love.audio.pause()
 end
 
@@ -376,7 +408,7 @@ love.test.audio.setEffect = function(test)
     type = 'chorus',
     volume = 10
   })
-  test:assertEquals(true, effect, 'check effect created')
+  test:assertTrue(effect, 'check effect created')
   -- check values set match
   local settings = love.audio.getEffect('testeffect')
   test:assertEquals('chorus', settings.type, 'check effect type')
@@ -439,8 +471,8 @@ love.test.audio.stop = function(test)
   -- check source is playing first
   local source = love.audio.newSource('resources/click.ogg', 'static')
   love.audio.play(source)
-  test:assertEquals(true, source:isPlaying(), 'check is playing')
+  test:assertTrue(source:isPlaying(), 'check is playing')
   -- check source is then stopped
   love.audio.stop()
-  test:assertEquals(false, source:isPlaying(), 'check stopped playing')
+  test:assertFalse(source:isPlaying(), 'check stopped playing')
 end

+ 9 - 0
testing/tests/data.lua

@@ -10,17 +10,21 @@
 
 -- ByteData (love.data.newByteData)
 love.test.data.ByteData = function(test)
+
   -- create new obj
   local data = love.data.newByteData('helloworld')
   test:assertObject(data)
+
   -- check properties match expected
   test:assertEquals('helloworld', data:getString(), 'check data string')
   test:assertEquals(10, data:getSize(), 'check data size')
+
   -- check cloning the bytedata
   local cloneddata = data:clone()
   test:assertObject(cloneddata)
   test:assertEquals('helloworld', cloneddata:getString(), 'check cloned data')
   test:assertEquals(10, cloneddata:getSize(), 'check cloned size')
+
   -- check pointer access if allowed
   if data:getFFIPointer() ~= nil and ffi ~= nil then
     local pointer = data:getFFIPointer()
@@ -28,24 +32,29 @@ love.test.data.ByteData = function(test)
     local byte5 = ptr[4]
     test:assertEquals('o', byte5)
   end
+
 end
 
 
 -- CompressedData (love.data.compress)
 love.test.data.CompressedData = function(test)
+
   -- create new compressed data
   local cdata = love.data.compress('data', 'zlib', 'helloworld', -1)
   test:assertObject(cdata)
   test:assertEquals('zlib', cdata:getFormat(), 'check format used')
+
   -- check properties match expected
   test:assertEquals(18, cdata:getSize())
   test:assertEquals('helloworld', love.data.decompress('data', cdata):getString())
+
   -- check cloning the data
   local clonedcdata = cdata:clone()
   test:assertObject(clonedcdata)
   test:assertEquals('zlib', clonedcdata:getFormat())
   test:assertEquals(18, clonedcdata:getSize())
   test:assertEquals('helloworld', love.data.decompress('data', clonedcdata):getString())
+
 end
 
 

+ 1 - 1
testing/tests/event.lua

@@ -69,7 +69,7 @@ love.test.event.quit = function(test)
   love.test.module.fakequit = true
   love.event.quit(0)
   -- if it failed we'd have quit here
-  test:assertEquals(true, true, 'check quit hook called')
+  test:assertTrue(true, 'check quit hook called')
 end
 
 

+ 29 - 18
testing/tests/filesystem.lua

@@ -10,11 +10,13 @@
 
 -- File (love.filesystem.newFile)
 love.test.filesystem.File = function(test)
+
   -- setup a file to play with
   local file1 = love.filesystem.openFile('data.txt', 'w')
   file1:write('helloworld')
   test:assertObject(file1)
   file1:close()
+
   -- test read mode
   file1:open('r')
   test:assertEquals('r', file1:getMode(), 'check read mode')
@@ -22,31 +24,34 @@ love.test.filesystem.File = function(test)
   test:assertEquals('helloworld', contents)
   test:assertEquals(10, size, 'check file read')
   test:assertEquals(10, file1:getSize())
-  local ok, err = file1:write('hello')
-  test:assertNotEquals(nil, err, 'check cant write in read mode')
+  local ok1, err1 = file1:write('hello')
+  test:assertNotEquals(nil, err1, 'check cant write in read mode')
   local iterator = file1:lines()
   test:assertNotEquals(nil, iterator, 'check can read lines')
   test:assertEquals('data.txt', file1:getFilename(), 'check filename matches')
   file1:close()
+
   -- test write mode
   file1:open('w')
   test:assertEquals('w', file1:getMode(), 'check write mode')
   contents, size = file1:read()
   test:assertEquals(nil, contents, 'check cant read file in write mode')
   test:assertEquals('string', type(size), 'check err message shown')
-  ok, err = file1:write('helloworld')
-  test:assertEquals(true, ok, 'check file write')
-  test:assertEquals(nil, err, 'check no err writing')
+  local ok2, err2 = file1:write('helloworld')
+  test:assertTrue(ok2, 'check file write')
+  test:assertEquals(nil, err2, 'check no err writing')
+
   -- test open/closing
   file1:open('r')
-  test:assertEquals(true, file1:isOpen(), 'check file is open')
+  test:assertTrue(file1:isOpen(), 'check file is open')
   file1:close()
-  test:assertEquals(false, file1:isOpen(), 'check file gets closed')
+  test:assertFalse(file1:isOpen(), 'check file gets closed')
   file1:close()
+
   -- test buffering and flushing
   file1:open('w')
-  ok, err = file1:setBuffer('full', 10000)
-  test:assertEquals(true, ok)
+  local ok3, err3 = file1:setBuffer('full', 10000)
+  test:assertTrue(ok3)
   test:assertEquals('full', file1:getBuffer())
   file1:write('replacedcontent')
   file1:flush()
@@ -55,6 +60,7 @@ love.test.filesystem.File = function(test)
   contents, size = file1:read()
   test:assertEquals('replacedcontent', contents, 'check buffered content was written')
   file1:close()
+
   -- loop through file data with seek/tell until EOF
   file1:open('r')
   local counter = 0
@@ -68,24 +74,29 @@ love.test.filesystem.File = function(test)
   end
   test:assertEquals(counter, 15)
   file1:close()
+
 end
 
 
 -- FileData (love.filesystem.newFileData)
 love.test.filesystem.FileData = function(test)
+
   -- create new obj
   local fdata = love.filesystem.newFileData('helloworld', 'test.txt')
   test:assertObject(fdata)
   test:assertEquals('test.txt', fdata:getFilename())
   test:assertEquals('txt', fdata:getExtension())
+
   -- check properties match expected
   test:assertEquals('helloworld', fdata:getString(), 'check data string')
   test:assertEquals(10, fdata:getSize(), 'check data size')
+
   -- check cloning the bytedata
   local clonedfdata = fdata:clone()
   test:assertObject(clonedfdata)
   test:assertEquals('helloworld', clonedfdata:getString(), 'check cloned data')
   test:assertEquals(10, clonedfdata:getSize(), 'check cloned size')
+
 end
 
 
@@ -166,8 +177,8 @@ love.test.filesystem.getDirectoryItems = function(test)
     if v == 'bar' and info.type == 'directory' then hasdir = true end
     if v == 'file1.txt' and info.type == 'file' then hasfile = true end
   end
-  test:assertEquals(true, hasfile, 'check file exists')
-  test:assertEquals(true, hasdir, 'check directory exists')
+  test:assertTrue(hasfile, 'check file exists')
+  test:assertTrue(hasdir, 'check directory exists')
   -- cleanup
   love.filesystem.remove('foo/file1.txt')
   love.filesystem.remove('foo/bar/file2.txt')
@@ -297,7 +308,7 @@ love.test.filesystem.load = function(test)
   test:assertEquals(1, chunk(), 'check lua file runs')
   -- check invalid lua file
   local ok, chunk, err = pcall(love.filesystem.load, 'test2.lua')
-  test:assertEquals(false, ok, 'check invalid lua file')
+  test:assertFalse(ok, 'check invalid lua file')
   -- cleanup
   love.filesystem.remove('test1.lua')
   love.filesystem.remove('test2.lua')
@@ -311,7 +322,7 @@ love.test.filesystem.mount = function(test)
   love.filesystem.write('test.zip', contents, size)
   -- check mounting file and check contents are mounted
   local success = love.filesystem.mount('test.zip', 'test')
-  test:assertEquals(true, success, 'check success')
+  test:assertTrue(success, 'check success')
   test:assertNotEquals(nil, love.filesystem.getInfo('test'), 'check mount not nil')
   test:assertEquals('directory', love.filesystem.getInfo('test').type, 'check directory made')
   test:assertNotEquals(nil, love.filesystem.getInfo('test/test.txt'), 'check file not nil')
@@ -362,11 +373,11 @@ love.test.filesystem.remove = function(test)
   love.filesystem.createDirectory('foo/bar')
   love.filesystem.write('foo/bar/file2.txt', 'helloworld')
   -- check removing files + dirs (should fail to remove dir if file inside)
-  test:assertEquals(false, love.filesystem.remove('foo'), 'check fail when file inside')
-  test:assertEquals(false, love.filesystem.remove('foo/bar'), 'check fail when file inside')
-  test:assertEquals(true, love.filesystem.remove('foo/bar/file2.txt'), 'check file removed')
-  test:assertEquals(true, love.filesystem.remove('foo/bar'), 'check subdirectory removed')
-  test:assertEquals(true, love.filesystem.remove('foo'), 'check directory removed')
+  test:assertFalse(love.filesystem.remove('foo'), 'check fail when file inside')
+  test:assertFalse(love.filesystem.remove('foo/bar'), 'check fail when file inside')
+  test:assertTrue(love.filesystem.remove('foo/bar/file2.txt'), 'check file removed')
+  test:assertTrue(love.filesystem.remove('foo/bar'), 'check subdirectory removed')
+  test:assertTrue(love.filesystem.remove('foo'), 'check directory removed')
   -- cleanup not needed here hopefully...
 end
 

+ 24 - 4
testing/tests/font.lua

@@ -10,15 +10,18 @@
 
 -- GlyphData (love.font.newGlyphData)
 love.test.font.GlyphData = function(test)
+
   -- create obj
   local rasterizer = love.font.newRasterizer('resources/font.ttf')
   local gdata = love.font.newGlyphData(rasterizer, 97) -- 'a'
   test:assertObject(gdata)
+
   -- check properties match expected
   test:assertNotNil(gdata:getString())
   test:assertEquals(128, gdata:getSize(), 'check data size')
   test:assertEquals(9, gdata:getAdvance(), 'check advance')
   test:assertEquals('la8', gdata:getFormat(), 'check format')
+
   -- @TODO 
   --[[
     currently these will return 0 and '' respectively as not implemented
@@ -29,37 +32,54 @@ love.test.font.GlyphData = function(test)
   ]]--
   --test:assertEquals(97, gdata:getGlyph(), 'check glyph number') - returns 0
   --test:assertEquals('a', gdata:getGlyphString(), 'check glyph string') - returns ''
+
+  -- check height + width
   test:assertEquals(8, gdata:getHeight(), 'check height')
   test:assertEquals(8, gdata:getWidth(), 'check width')
-  -- check boundary
+
+  -- check boundary / dimensions
   local x, y, w, h = gdata:getBoundingBox()
   local dw, dh = gdata:getDimensions()
-  local bw, bh = gdata:getBearing()
   test:assertEquals(0, x, 'check bbox x')
   test:assertEquals(-3, y, 'check bbox y')
   test:assertEquals(8, w, 'check bbox w')
   test:assertEquals(14, h, 'check bbox h')
   test:assertEquals(8, dw, 'check dim width')
   test:assertEquals(8, dh, 'check dim height')
+
+  -- check bearing
+  local bw, bh = gdata:getBearing()
   test:assertEquals(0, bw, 'check bearing w')
   test:assertEquals(11, bh, 'check bearing h')
+
 end
 
 
 -- Rasterizer (love.font.newRasterizer)
 love.test.font.Rasterizer = function(test)
+
   -- create obj
   local rasterizer = love.font.newRasterizer('resources/font.ttf')
   test:assertObject(rasterizer)
-  -- check properties match
+
+  -- check advance
   test:assertEquals(9, rasterizer:getAdvance(), 'check advance')
+
+  -- check ascent/descent
   test:assertEquals(9, rasterizer:getAscent(), 'check ascent')
   test:assertEquals(-3, rasterizer:getDescent(), 'check descent')
+
+  -- check glyphcount
   test:assertEquals(77, rasterizer:getGlyphCount(), 'check glyph count')
+
+  -- check specific glyphs
   test:assertObject(rasterizer:getGlyphData('L'))
+  test:assertTrue(rasterizer:hasGlyphs('L', 'O', 'V', 'E'), 'check LOVE')
+
+  -- check height + lineheight
   test:assertEquals(12, rasterizer:getHeight(), 'check height')
   test:assertEquals(15, rasterizer:getLineHeight(), 'check line height')
-  test:assertEquals(true, rasterizer:hasGlyphs('L', 'O', 'V', 'E'), 'check LOVE')
+
 end
 
 

File diff suppressed because it is too large
+ 364 - 196
testing/tests/graphics.lua


+ 27 - 9
testing/tests/image.lua

@@ -10,38 +10,52 @@
 
 -- CompressedImageData (love.image.newCompressedImageData)
 love.test.image.CompressedImageData = function(test)
+
   -- create obj
   local idata = love.image.newCompressedData('resources/love.dxt1')
   test:assertObject(idata)
-  -- check data properties
+
+  -- check string + size
   test:assertNotEquals(nil, idata:getString(), 'check data string')
   test:assertEquals(2744, idata:getSize(), 'check data size')
-  -- check img data properties
+
+  -- check img dimensions
   local iw, ih = idata:getDimensions()
   test:assertEquals(64, iw, 'check image dimension w')
   test:assertEquals(64, ih, 'check image dimension h')
-  test:assertEquals('DXT1', idata:getFormat(), 'check image format')
   test:assertEquals(64, idata:getWidth(), 'check image direct w')
   test:assertEquals(64, idata:getHeight(), 'check image direct h')
+
+  -- check format
+  test:assertEquals('DXT1', idata:getFormat(), 'check image format')
+
+  -- check mipmap count
   test:assertEquals(7, idata:getMipmapCount(), 'check mipmap count')
+
 end
 
 
 -- ImageData (love.image.newImageData)
 love.test.image.ImageData = function(test)
+
   -- create obj
   local idata = love.image.newImageData('resources/love.png')
   test:assertObject(idata)
-  -- check data properties
+
+  -- check string + size
   test:assertNotEquals(nil, idata:getString(), 'check data string')
   test:assertEquals(16384, idata:getSize(), 'check data size')
-  -- check img data properties
+
+  -- check img dimensions
   local iw, ih = idata:getDimensions()
   test:assertEquals(64, iw, 'check image dimension w')
   test:assertEquals(64, ih, 'check image dimension h')
-  test:assertEquals('rgba8', idata:getFormat(), 'check image format')
   test:assertEquals(64, idata:getWidth(), 'check image direct w')
   test:assertEquals(64, idata:getHeight(), 'check image direct h')
+
+  -- check format
+  test:assertEquals('rgba8', idata:getFormat(), 'check image format')
+  
   -- manipulate image data so white heart is black
   local mapdata = function(x, y, r, g, b, a)
     if r == 1 and g == 1 and b == 1 then
@@ -52,20 +66,24 @@ love.test.image.ImageData = function(test)
   idata:mapPixel(mapdata, 0, 0, 64, 64)
   local r1, g1, b1 = idata:getPixel(25, 25)
   test:assertEquals(0, r1+g1+b1, 'check mapped black')
+
   -- map some other data into the idata
   local idata2 = love.image.newImageData('resources/loveinv.png')
   idata:paste(idata2, 0, 0, 0, 0)
   r1, g1, b1 = idata:getPixel(25, 25)
   test:assertEquals(3, r1+g1+b1, 'check back to white')
+
   -- set pixels directly
   idata:setPixel(25, 25, 1, 0, 0, 1)
-  r1, g1, b1 = idata:getPixel(25, 25)
-  test:assertEquals(1, r1+g1+b1, 'check set to red')
+  local r2, g2, b2 = idata:getPixel(25, 25)
+  test:assertEquals(1, r2+g2+b2, 'check set to red')
+
   -- check encoding to an image
   idata:encode('png', 'test-encode.png')
   local read = love.filesystem.openFile('test-encode.png', 'r')
   test:assertNotNil(read)
   love.filesystem.remove('test-encode.png')
+
 end
 
 
@@ -81,7 +99,7 @@ end
 -- https://love2d.org/wiki/CompressedImageFormat
 -- also need to be platform dependent (e.g. dxt not suppored on phones)
 love.test.image.isCompressed = function(test)
-  test:assertEquals(true, love.image.isCompressed('resources/love.dxt1'), 
+  test:assertTrue(love.image.isCompressed('resources/love.dxt1'), 
     'check dxt1 valid compressed image')
 end
 

+ 71 - 49
testing/tests/math.lua

@@ -10,30 +10,36 @@
 
 -- BezierCurve (love.math.newBezierCurve)
 love.test.math.BezierCurve = function(test)
+
   -- create obj
   local curve = love.math.newBezierCurve(1, 1, 2, 2, 3, 1)
   local px, py = curve:getControlPoint(2)
   test:assertObject(curve)
+
   -- check initial properties
   test:assertCoords({2, 2}, {px, py}, 'check point x/y')
   test:assertEquals(3, curve:getControlPointCount(), 'check 3 points')
   test:assertEquals(2, curve:getDegree(), 'check degree is points-1')
+
   -- check some values on the curve
   test:assertEquals(1, curve:evaluate(0), 'check curve evaluation 0')
-  test:assertEquals(120, math.floor(curve:evaluate(0.1)*100), 'check curve evaluation 0.1')
-  test:assertEquals(140, math.floor(curve:evaluate(0.2)*100), 'check curve evaluation 0.2')
-  test:assertEquals(200, math.floor(curve:evaluate(0.5)*100), 'check curve evaluation 0.5')
+  test:assertRange(curve:evaluate(0.1), 1.2, 1.3, 'check curve evaluation 0.1')
+  test:assertRange(curve:evaluate(0.2), 1.4, 1.5, 'check curve evaluation 0.2')
+  test:assertRange(curve:evaluate(0.5), 2, 2.1, 'check curve evaluation 0.5')
   test:assertEquals(3, curve:evaluate(1), 'check curve evaluation 1')
+
   -- check derivative
   local deriv = curve:getDerivative()
   test:assertObject(deriv)
   test:assertEquals(2, deriv:getControlPointCount(), 'check deriv points')
-  test:assertEquals(200, math.floor(deriv:evaluate(0.1)*100), 'check deriv evaluation 0.1')
+  test:assertRange(deriv:evaluate(0.1), 2, 2.1, 'check deriv evaluation 0.1')
+
   -- check segment
   local segment = curve:getSegment(0, 0.5)
   test:assertObject(segment)
   test:assertEquals(3, segment:getControlPointCount(), 'check segment points')
-  test:assertEquals(109, math.floor(segment:evaluate(0.1)*100), 'check segment evaluation 0.1')
+  test:assertRange(segment:evaluate(0.1), 1, 1.1, 'check segment evaluation 0.1')
+
   -- mess with control points
   curve:removeControlPoint(2)
   curve:insertControlPoint(4, 1, -1)
@@ -47,11 +53,13 @@ love.test.math.BezierCurve = function(test)
   test:assertCoords({1, 1}, {px1, py1}, 'check modified point 1')
   test:assertCoords({5, 3}, {px2, py2}, 'check modified point 1')
   test:assertCoords({3, 1}, {px3, py3}, 'check modified point 1')
+
   -- check render lists
   local coords1 = curve:render(5)
   local coords2 = curve:renderSegment(0, 0.1, 5)
   test:assertEquals(196, #coords1, 'check coords')
   test:assertEquals(20, #coords2, 'check segment coords')
+
   -- check translation values
   px, py = curve:getControlPoint(2)
   test:assertCoords({3, 2}, {px, py}, 'check pretransform x/y')
@@ -64,6 +72,7 @@ love.test.math.BezierCurve = function(test)
   curve:translate(5, -5)
   px, py = curve:getControlPoint(2)
   test:assertCoords({1, 1}, {px, py}, 'check translated x/y')
+
 end
 
 
@@ -71,32 +80,40 @@ end
 -- @NOTE as this checks random numbers the chances this fails is very unlikely, but not 0...
 -- if you've managed to proc it congrats! your prize is to rerun the testsuite again
 love.test.math.RandomGenerator = function(test)
+
   -- create object
   local rng1 = love.math.newRandomGenerator(3418323524, 20529293)
   test:assertObject(rng1)
+
   -- check set properties
   local low, high = rng1:getSeed()
   test:assertEquals(3418323524, low, 'check seed low')
   test:assertEquals(20529293, high, 'check seed high')
+
   -- check states
   local rng2 = love.math.newRandomGenerator(1448323524, 10329293)
   test:assertNotEquals(rng1:random(), rng2:random(), 'check not matching states')
   test:assertNotEquals(rng1:randomNormal(), rng2:randomNormal(), 'check not matching states')
+
   -- check setting state works
   rng2:setState(rng1:getState())
   test:assertEquals(rng1:random(), rng2:random(), 'check now matching')
+
   -- check overwriting seed works, should change output
   rng1:setSeed(os.time())
   test:assertNotEquals(rng1:random(), rng2:random(), 'check not matching states')
   test:assertNotEquals(rng1:randomNormal(), rng2:randomNormal(), 'check not matching states')
+
 end
 
 
 -- Transform (love.math.Transform)
 love.test.math.Transform = function(test)
+
   -- create obj
   local transform = love.math.newTransform(0, 0, 0, 1, 1, 0, 0, 0, 0)
   test:assertObject(transform)
+
   -- set some values and check the matrix and transformPoint values
   transform:translate(10, 8)
   transform:scale(2, 3)
@@ -107,16 +124,19 @@ love.test.math.Transform = function(test)
   transform:reset()
   px, py = transform:transformPoint(1, 1)
   test:assertCoords({1, 1}, {px, py}, 'check reset')
+
   -- apply a transform to another transform
   local transform2 = love.math.newTransform()
   transform2:translate(5, 3)
   transform:apply(transform2)
   px, py = transform:transformPoint(1, 1)
   test:assertCoords({6, 4}, {px, py}, 'check apply other transform')
+
   -- check cloning a transform
   local transform3 = transform:clone()
   px, py = transform3:transformPoint(1, 1)
   test:assertCoords({6, 4}, {px, py}, 'check clone transform')
+
   -- check inverse and inverseTransform
   transform:reset()
   transform:translate(-14, 6)
@@ -124,6 +144,7 @@ love.test.math.Transform = function(test)
   transform:inverse()
   px, py = transform:transformPoint(0, 0)
   test:assertCoords({-px, -py}, {ipx, ipy}, 'check inverse points transform')
+
   -- check matrix manipulation
   transform:setTransformation(0, 0, 0, 1, 1, 0, 0, 0, 0)
   transform:translate(4, 4)
@@ -134,13 +155,15 @@ love.test.math.Transform = function(test)
   transform:setMatrix(m1, m2, m3, 3, m5, m6, m7, 1, m9, m10, m11, m12, m13, m14, m15, m16)
   px, py = transform:transformPoint(1, 1)
   test:assertCoords({4, 2}, {px, py}, 'check set matrix')
+
   -- check affine vs non affine
   transform:reset()
-  test:assertEquals(true, transform:isAffine2DTransform(), 'check affine 1')
+  test:assertTrue(transform:isAffine2DTransform(), 'check affine 1')
   transform:translate(4, 3)
-  test:assertEquals(true, transform:isAffine2DTransform(), 'check affine 2')
+  test:assertTrue(transform:isAffine2DTransform(), 'check affine 2')
   transform:setMatrix(1, 3, 4, 5.5, 1, 4.5, 2, 1, 3.4, 5.1, 4.1, 13, 1, 1, 2, 3)
-  test:assertEquals(false, transform:isAffine2DTransform(), 'check not affine')
+  test:assertFalse(transform:isAffine2DTransform(), 'check not affine')
+
 end
 
 
@@ -154,46 +177,46 @@ end
 -- love.math.colorFromBytes
 love.test.math.colorFromBytes = function(test)
   -- check random value
-  local r, g, b, a = love.math.colorFromBytes(51, 51, 51, 51)
-  test:assertEquals(r, 0.2, 'check r from bytes')
-  test:assertEquals(g, 0.2, 'check g from bytes')
-  test:assertEquals(b, 0.2, 'check b from bytes')
-  test:assertEquals(a, 0.2, 'check a from bytes')
+  local r1, g1, b1, a1 = love.math.colorFromBytes(51, 51, 51, 51)
+  test:assertEquals(r1, 0.2, 'check r from bytes')
+  test:assertEquals(g1, 0.2, 'check g from bytes')
+  test:assertEquals(b1, 0.2, 'check b from bytes')
+  test:assertEquals(a1, 0.2, 'check a from bytes')
   -- check "max" value
-  r, g, b, a = love.math.colorFromBytes(255, 255, 255, 255)
-  test:assertEquals(r, 1, 'check r from bytes')
-  test:assertEquals(g, 1, 'check g from bytes')
-  test:assertEquals(b, 1, 'check b from bytes')
-  test:assertEquals(a, 1, 'check a from bytes')
+  local r2, g2, b2, a2 = love.math.colorFromBytes(255, 255, 255, 255)
+  test:assertEquals(r2, 1, 'check r from bytes')
+  test:assertEquals(g2, 1, 'check g from bytes')
+  test:assertEquals(b2, 1, 'check b from bytes')
+  test:assertEquals(a2, 1, 'check a from bytes')
   -- check "min" value
-  r, g, b, a = love.math.colorFromBytes(0, 0, 0, 0)
-  test:assertEquals(r, 0, 'check r from bytes')
-  test:assertEquals(g, 0, 'check g from bytes')
-  test:assertEquals(b, 0, 'check b from bytes')
-  test:assertEquals(a, 0, 'check a from bytes')
+  local r3, g3, b3, a3 = love.math.colorFromBytes(0, 0, 0, 0)
+  test:assertEquals(r3, 0, 'check r from bytes')
+  test:assertEquals(g3, 0, 'check g from bytes')
+  test:assertEquals(b3, 0, 'check b from bytes')
+  test:assertEquals(a3, 0, 'check a from bytes')
 end
 
 
 -- love.math.colorToBytes
 love.test.math.colorToBytes = function(test)
   -- check random value
-  local r, g, b, a = love.math.colorToBytes(0.2, 0.2, 0.2, 0.2)
-  test:assertEquals(r, 51, 'check bytes from r')
-  test:assertEquals(g, 51, 'check bytes from g')
-  test:assertEquals(b, 51, 'check bytes from b')
-  test:assertEquals(a, 51, 'check bytes from a')
+  local r1, g1, b1, a1 = love.math.colorToBytes(0.2, 0.2, 0.2, 0.2)
+  test:assertEquals(r1, 51, 'check bytes from r')
+  test:assertEquals(g1, 51, 'check bytes from g')
+  test:assertEquals(b1, 51, 'check bytes from b')
+  test:assertEquals(a1, 51, 'check bytes from a')
   -- check "max" value
-  r, g, b, a = love.math.colorToBytes(1, 1, 1, 1)
-  test:assertEquals(r, 255, 'check bytes from r')
-  test:assertEquals(g, 255, 'check bytes from g')
-  test:assertEquals(b, 255, 'check bytes from b')
-  test:assertEquals(a, 255, 'check bytes from a')
+  local r2, g2, b2, a2 = love.math.colorToBytes(1, 1, 1, 1)
+  test:assertEquals(r2, 255, 'check bytes from r')
+  test:assertEquals(g2, 255, 'check bytes from g')
+  test:assertEquals(b2, 255, 'check bytes from b')
+  test:assertEquals(a2, 255, 'check bytes from a')
   -- check "min" value
-  r, g, b, a = love.math.colorToBytes(0, 0, 0, 0)
-  test:assertEquals(r, 0, 'check bytes from r')
-  test:assertEquals(g, 0, 'check bytes from g')
-  test:assertEquals(b, 0, 'check bytes from b')
-  test:assertEquals(a, 0, 'check bytes from a')
+  local r3, g3, b3, a3 = love.math.colorToBytes(0, 0, 0, 0)
+  test:assertEquals(r3, 0, 'check bytes from r')
+  test:assertEquals(g3, 0, 'check bytes from g')
+  test:assertEquals(b3, 0, 'check bytes from b')
+  test:assertEquals(a3, 0, 'check bytes from a')
 end
 
 
@@ -229,8 +252,8 @@ end
 love.test.math.isConvex = function(test)
   local isconvex = love.math.isConvex({0, 0, 1, 0, 1, 1, 1, 0, 0, 0}) -- square
   local notconvex = love.math.isConvex({1, 2, 2, 4, 3, 4, 2, 1, 3, 1}) -- weird shape
-  test:assertEquals(true, isconvex, 'check polygon convex')
-  test:assertEquals(false, notconvex, 'check polygon not convex')
+  test:assertTrue(isconvex, 'check polygon convex')
+  test:assertFalse(notconvex, 'check polygon not convex')
 end
 
 
@@ -276,11 +299,10 @@ love.test.math.perlinNoise = function(test)
   local noise2 = love.math.perlinNoise(1, 10)
   local noise3 = love.math.perlinNoise(1043, 31.123, 999)
   local noise4 = love.math.perlinNoise(99.222, 10067, 8, 1843)
-  -- rounded to avoid floating point issues 
-  test:assertEquals(50000, math.floor(noise1*100000), 'check noise 1 dimension')
-  test:assertEquals(50000, math.floor(noise2*100000), 'check noise 2 dimensions')
-  test:assertEquals(56297, math.floor(noise3*100000), 'check noise 3 dimensions')
-  test:assertEquals(52579, math.floor(noise4*100000), 'check noise 4 dimensions')
+  test:assertRange(noise1, 0.5, 0.51, 'check noise 1 dimension')
+  test:assertRange(noise2, 0.5, 0.51, 'check noise 2 dimensions')
+  test:assertRange(noise3, 0.56, 0.57, 'check noise 3 dimensions')
+  test:assertRange(noise4, 0.52, 0.53, 'check noise 4 dimensions')
 end
 
 
@@ -293,10 +315,10 @@ love.test.math.simplexNoise = function(test)
   local noise3 = love.math.simplexNoise(1043, 31.123, 999)
   local noise4 = love.math.simplexNoise(99.222, 10067, 8, 1843)
   -- rounded to avoid floating point issues 
-  test:assertEquals(50000, math.floor(noise1*100000), 'check noise 1 dimension')
-  test:assertEquals(47863, math.floor(noise2*100000), 'check noise 2 dimensions')
-  test:assertEquals(26440, math.floor(noise3*100000), 'check noise 3 dimensions')
-  test:assertEquals(53360, math.floor(noise4*100000), 'check noise 4 dimensions')
+  test:assertRange(noise1, 0.5, 0.51, 'check noise 1 dimension')
+  test:assertRange(noise2, 0.47, 0.48, 'check noise 2 dimensions')
+  test:assertRange(noise3, 0.26, 0.27, 'check noise 3 dimensions')
+  test:assertRange(noise4, 0.53, 0.54, 'check noise 4 dimensions')
 end
 
 

+ 289 - 153
testing/tests/physics.lua

@@ -10,6 +10,7 @@
 
 -- Body (love.physics.newBody)
 love.test.physics.Body = function(test)
+
   -- create body
   local world = love.physics.newWorld(1, 1, true)
   local body1 = love.physics.newBody(world, 0, 0, 'static')
@@ -17,148 +18,197 @@ love.test.physics.Body = function(test)
   love.physics.newRectangleShape(body1, 5, 5, 10, 10)
   love.physics.newRectangleShape(body2, 5, 5, 10, 10)
   test:assertObject(body1)
-  -- check state properties
-  test:assertEquals(true, body1:isActive(), 'check active by def')
-  test:assertEquals(false, body1:isBullet(), 'check not bullet by def')
+
+  -- check body active
+  test:assertTrue(body1:isActive(), 'check active by def')
+
+  -- check body bullet
+  test:assertFalse(body1:isBullet(), 'check not bullet by def')
   body1:setBullet(true)
-  test:assertEquals(true, body1:isBullet(), 'check set bullet')
-  test:assertEquals(false, body1:isFixedRotation(), 'check fix rot def')
+  test:assertTrue(body1:isBullet(), 'check set bullet')
+
+  -- check fixed rotation
+  test:assertFalse(body1:isFixedRotation(), 'check fix rot def')
   body1:setFixedRotation(true)
-  test:assertEquals(true, body1:isFixedRotation(), 'check set fix rot')
-  test:assertEquals(true, body1:isSleepingAllowed(), 'check sleep def')
+  test:assertTrue(body1:isFixedRotation(), 'check set fix rot')
+
+  -- check sleeping/waking
+  test:assertTrue(body1:isSleepingAllowed(), 'check sleep def')
   body1:setSleepingAllowed(false)
-  test:assertEquals(false, body1:isSleepingAllowed(), 'check set sleep')
+  test:assertFalse(body1:isSleepingAllowed(), 'check set sleep')
   body1:setSleepingAllowed(true)
   world:update(1)
-  test:assertEquals(false, body1:isAwake(), 'check fell asleep')
+  test:assertFalse(body1:isAwake(), 'check fell asleep')
   body1:setSleepingAllowed(false)
   body1:setType('dynamic')
-  test:assertEquals(true, body1:isAwake(), 'check waking up')
-  test:assertEquals(false, body1:isTouching(body2))
+  test:assertTrue(body1:isAwake(), 'check waking up')
+
+  -- check touching
+  test:assertFalse(body1:isTouching(body2))
   body2:setPosition(5, 5)
   world:update(1)
-  test:assertEquals(true, body1:isTouching(body2))
-  -- check body properties
+  test:assertTrue(body1:isTouching(body2))
+
+  -- check children lists
   test:assertEquals(1, #body1:getContacts(), 'check contact list')
   test:assertEquals(0, #body1:getJoints(), 'check joints list')
   love.physics.newDistanceJoint(body1, body2, 5, 5, 10, 10, true)
   test:assertEquals(1, #body1:getJoints(), 'check joints list')
+
+  -- check local points
   local x, y = body1:getLocalCenter()
-  test:assertEquals(5, math.floor(x), 'check local center x')
-  test:assertEquals(5, math.floor(y), 'check local center y')
+  test:assertRange(x, 5, 6, 'check local center x')
+  test:assertRange(y, 5, 6, 'check local center y')
   local lx, ly = body1:getLocalPoint(10, 10)
-  test:assertEquals(10, math.floor(lx), 'check local point x')
-  test:assertEquals(9, math.floor(ly), 'check local point y')
+  test:assertRange(lx, 10, 11, 'check local point x')
+  test:assertRange(ly, 9, 10, 'check local point y')
   local lx1, ly1, lx2, ly2 = body1:getLocalPoints(0, 5, 5, 10)
-  test:assertEquals(0, math.floor(lx1), 'check local points x 1')
-  test:assertEquals(4, math.floor(ly1), 'check local points y 1')
-  test:assertEquals(5, math.floor(lx2), 'check local points x 2')
-  test:assertEquals(9, math.floor(ly2), 'check local points y 2')
+  test:assertRange(lx1, 0, 1, 'check local points x 1')
+  test:assertRange(ly1, 3, 4, 'check local points y 1')
+  test:assertRange(lx2, 5, 6, 'check local points x 2')
+  test:assertRange(ly2, 9, 10, 'check local points y 2')
+
+  -- check world points
   local wx, wy = body1:getWorldPoint(10.4, 9)
-  test:assertEquals(10, math.floor(wx), 'check world point x')
-  test:assertEquals(10, math.floor(wy), 'check world point y')
+  test:assertRange(wx, 10, 11, 'check world point x')
+  test:assertRange(wy, 10, 11, 'check world point y')
   local wx1, wy1, wx2, wy2 = body1:getWorldPoints(0.4, 4, 5.4, 9)
-  test:assertEquals(0, math.floor(wx1), 'check world points x 1')
-  test:assertEquals(5, math.floor(wy1), 'check world points y 1')
-  test:assertEquals(5, math.floor(wx2), 'check world points x 2')
-  test:assertEquals(10, math.floor(wy2), 'check world points y 2')
+  test:assertRange(wx1, 0, 1, 'check world points x 1')
+  test:assertRange(wy1, 5, 6, 'check world points y 1')
+  test:assertRange(wx2, 5, 6, 'check world points x 2')
+  test:assertRange(wy2, 10, 11, 'check world points y 2')
+
+  -- check angular damping + velocity
   test:assertEquals(0, body1:getAngularDamping(), 'check angular damping')
   test:assertEquals(0, body1:getAngularVelocity(), 'check angular velocity')
+
+  -- check world props
   test:assertObject(body1:getWorld())
   test:assertEquals(2, body1:getWorld():getBodyCount(), 'check world count')
   local cx, cy = body1:getWorldCenter()
-  test:assertEquals(46, math.floor(cx*10), 'check world center x')
-  test:assertEquals(60, math.floor(cy*10), 'check world center y')
+  test:assertRange(cx, 4, 5, 'check world center x')
+  test:assertRange(cy, 6, 7, 'check world center y')
   local vx, vy = body1:getWorldVector(5, 10)
   test:assertEquals(5, vx, 'check vector x')
   test:assertEquals(10, vy, 'check vector y')
-  test:assertEquals(555, math.floor(body1:getInertia()*100), 'check inertia')
-  -- check get/set properties
+
+  -- check inertia
+  test:assertRange(body1:getInertia(), 5, 6, 'check inertia')
+
+  -- check angle
   test:assertEquals(0, body1:getAngle(), 'check def angle')
   body1:setAngle(90 * (math.pi/180))
   test:assertEquals(math.floor(math.pi/2*100), math.floor(body1:getAngle()*100), 'check set angle')
+
+  -- check gravity scale
   test:assertEquals(1, body1:getGravityScale(), 'check def grav')
   body1:setGravityScale(2)
   test:assertEquals(2, body1:getGravityScale(), 'check change grav')
+
+  -- check damping
   test:assertEquals(0, body1:getLinearDamping(), 'check def lin damping')
   body1:setLinearDamping(0.1)
-  test:assertEquals(1, math.floor(body1:getLinearDamping()*10), 'check change lin damping')
-  x, y = body1:getLinearVelocity()
-  test:assertEquals(1, x, 'check def lin velocity x')
-  test:assertEquals(1, y, 'check def lin velocity y')
+  test:assertRange(body1:getLinearDamping(), 0, 0.2, 'check change lin damping')
+
+  -- check velocity
+  local x2, y2 = body1:getLinearVelocity()
+  test:assertEquals(1, x2, 'check def lin velocity x')
+  test:assertEquals(1, y2, 'check def lin velocity y')
   body1:setLinearVelocity(4, 5)
-  x, y = body1:getLinearVelocity()
-  test:assertEquals(4, x, 'check change lin velocity x')
-  test:assertEquals(5, y, 'check change lin velocity y')
-  test:assertEquals(1, math.floor(body1:getMass()*10), 'check def mass')
+  local x3, y3 = body1:getLinearVelocity()
+  test:assertEquals(4, x3, 'check change lin velocity x')
+  test:assertEquals(5, y3, 'check change lin velocity y')
+
+  -- check mass 
+  test:assertRange(body1:getMass(), 0.1, 0.2, 'check def mass')
   body1:setMass(10)
   test:assertEquals(10, body1:getMass(), 'check change mass')
   body1:setMassData(3, 5, 10, 1)
-  local x, y, mass, inertia = body1:getMassData()
-  test:assertEquals(3, x, 'check mass data change x')
-  test:assertEquals(5, y, 'check mass data change y')
-  test:assertEquals(10, mass, 'check mass data change mass')
-  test:assertEquals(340, math.floor(inertia), 'check mass data change inertia')
+  local x4, y4, mass4, inertia4 = body1:getMassData()
+  test:assertEquals(3, x4, 'check mass data change x')
+  test:assertEquals(5, y4, 'check mass data change y')
+  test:assertEquals(10, mass4, 'check mass data change mass')
+  test:assertRange(inertia4, 340, 341, 'check mass data change inertia')
   body1:resetMassData()
-  x, y, mass, inertia = body1:getMassData()
-  test:assertEquals(5, math.floor(x), 'check mass data reset x')
-  test:assertEquals(5, math.floor(y), 'check mass data reset y')
-  test:assertEquals(1, math.floor(mass*10), 'check mass data reset mass')
-  test:assertEquals(5, math.floor(inertia), 'check mass data reset inertia')
-  x, y = body1:getPosition()
-  test:assertEquals(-1, math.floor(x), 'check position x')
-  test:assertEquals(0, math.floor(y), 'check position y')
+  local x5, y5, mass5, inertia5 = body1:getMassData()
+  test:assertRange(x5, 5, 6, 'check mass data reset x')
+  test:assertRange(y5, 5, 6, 'check mass data reset y')
+  test:assertRange(mass5, 0.1, 0.2, 'check mass data reset mass')
+  test:assertRange(inertia5, 5, 6, 'check mass data reset inertia')
+
+  -- check position
+  local x6, y6 = body1:getPosition()
+  test:assertRange(x6, -1, 0, 'check position x')
+  test:assertRange(y6, 0, 1, 'check position y')
   body1:setPosition(10, 4)
-  x, y = body1:getPosition()
-  test:assertEquals(10, math.floor(x), 'check set position x')
-  test:assertEquals(4, math.floor(y), 'check set position y')
+  local x7, y7 = body1:getPosition()
+  test:assertEquals(x7, 10, 'check set position x')
+  test:assertEquals(y7, 4, 'check set position y')
+
+  -- check type
   test:assertEquals('dynamic', body1:getType(), 'check type match')
   body1:setType('kinematic')
   body1:setType('static')
   test:assertEquals('static', body1:getType(), 'check type change')
+
+  -- check userdata
   test:assertEquals(nil, body1:getUserData(), 'check user data')
   body1:setUserData({ love = 'cool' })
   test:assertEquals('cool', body1:getUserData().love, 'check set user data')
+
+  -- check x/y direct
   test:assertEquals(10, body1:getX(), 'check get x')
   test:assertEquals(4, body1:getY(), 'check get y')
   body1:setX(0)
   body1:setY(0)
   test:assertEquals(0, body1:getX(), 'check get x')
   test:assertEquals(0, body1:getY(), 'check get y')
-  -- apply some force
+
+  -- apply angular impulse
   local vel = body2:getAngularVelocity()
-  test:assertEquals(0, math.floor(vel), 'check velocity before')
+  test:assertRange(vel, 0, 0, 'check velocity before')
   body2:applyAngularImpulse(10)
-  vel = body2:getAngularVelocity()
-  test:assertEquals(54, math.floor(vel*10), 'check velocity after 1')
-  local ang = body2:getAngle()
-  test:assertEquals(149, math.floor(ang*1000), 'check initial angle')
+  local vel1 = body2:getAngularVelocity()
+  test:assertRange(vel1, 5, 6, 'check velocity after 1')
+
+  -- apply standard force
+  local ang1 = body2:getAngle()
+  test:assertRange(ang1, 0.1, 0.2, 'check initial angle 1')
   body2:applyForce(2, 3)
   world:update(2)
-  vel = body2:getAngularVelocity()
-  ang = body2:getAngle()
-  test:assertEquals(-84, math.floor(ang*1000), 'check angle after')
-  test:assertEquals(124, math.floor(vel*100), 'check velocity after 2')
+  local vel2 = body2:getAngularVelocity()
+  local ang2 = body2:getAngle()
+  test:assertRange(ang2, -0.1, 0, 'check angle after 2')
+  test:assertRange(vel2, 1, 2, 'check velocity after 2')
+
+  -- apply linear impulse
   body2:applyLinearImpulse(-4, -59)
   world:update(1)
-  ang = body2:getAngle()
-  vel = body2:getAngularVelocity()
-  test:assertEquals(-1572, math.floor(ang*1000), 'check angle after 2')
-  test:assertEquals(9, math.floor(vel*100000000), 'check velocity after 3')
+  local ang3 = body2:getAngle()
+  local vel3 = body2:getAngularVelocity()
+  test:assertRange(ang3, -2, -1, 'check angle after 3')
+  test:assertRange(vel3, 0, 1, 'check velocity after 3')
+
+  -- apply torque
   body2:applyTorque(4)
   world:update(2)
-  ang = body2:getAngle()
-  vel = body2:getAngularVelocity()
-  test:assertEquals(-912, math.floor(ang*1000), 'check angle after 3')
-  test:assertEquals(321, math.floor(vel*1000), 'check velocity after 4')
-  test:assertEquals(false, body1:isDestroyed(), 'check not destroyed')
+  local ang4 = body2:getAngle()
+  local vel4 = body2:getAngularVelocity()
+  test:assertRange(ang4, -1, 0, 'check angle after 4')
+  test:assertRange(vel4, 0, 1, 'check velocity after 4')
+
+  -- check destroy
+  test:assertFalse(body1:isDestroyed(), 'check not destroyed')
   body1:destroy()
-  test:assertEquals(true, body1:isDestroyed(), 'check destroyed')
+  test:assertTrue(body1:isDestroyed(), 'check destroyed')
+
 end
 
 
 -- Contact (love.physics.World:getContacts)
 love.test.physics.Contact = function(test)
+
+  -- create a setup so we can access some contact objects
   local world = love.physics.newWorld(1, 1, true)
   local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
   local body2 = love.physics.newBody(world, 10, 10, 'dynamic')
@@ -166,120 +216,167 @@ love.test.physics.Contact = function(test)
   local rectangle2 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
   rectangle1:setUserData('rec1')
   rectangle2:setUserData('rec2')
+
+  -- used to check for collisions + no. of collisions
   local collided = false
   local pass = 1
+
+  -- set callback for contact start 
   world:setCallbacks(
     function(shape_a, shape_b, contact)
       collided = true
+
+      -- check contact object
       test:assertObject(contact)
+
+      -- check child indices
       local indexA, indexB = contact:getChildren()
       test:assertEquals(1, indexA, 'check child indice a')
       test:assertEquals(1, indexB, 'check child indice b')
+
+      -- check shapes match using userdata
       local shapeA, shapeB = contact:getShapes()
       test:assertEquals(shape_a:getUserData(), shapeA:getUserData(), 'check shape a matches')
       test:assertEquals(shape_b:getUserData(), shapeB:getUserData(), 'check shape b matches')
+
+      -- check normal pos
       local nx, ny = contact:getNormal()
       test:assertEquals(1, nx, 'check normal x')
       test:assertEquals(0, ny, 'check normal y')
+
+      -- check actual pos
       local px1, py1, px2, py2 = contact:getPositions()
-      test:assertEquals(5, math.floor(px1), 'check collide x 1')
-      test:assertEquals(5, math.floor(py1), 'check collide y 1')
-      test:assertEquals(5, math.floor(px2), 'check collide x 2')
-      test:assertEquals(5, math.floor(py2), 'check collide y 2')
-      test:assertEquals(true, contact:isTouching(), 'check touching')
+      test:assertRange(px1, 5, 6, 'check collide x 1')
+      test:assertRange(py1, 5, 6, 'check collide y 1')
+      test:assertRange(px2, 5, 6, 'check collide x 2')
+      test:assertRange(py2, 5, 6, 'check collide y 2')
+
+      -- check touching
+      test:assertTrue(contact:isTouching(), 'check touching')
+
+      -- check enabled (we pass through twice to test on/off)
       test:assertEquals(pass == 1, contact:isEnabled(), 'check enabled for pass ' .. tostring(pass))
-      test:assertEquals(2, math.floor(contact:getFriction()*10), 'check def friction')
+
+      -- check friction
+      test:assertRange(contact:getFriction(), 0.2, 0.3, 'check def friction')
       contact:setFriction(0.1)
-      test:assertEquals(1, math.floor(contact:getFriction()*10), 'check set friction')
+      test:assertRange(contact:getFriction(), 0.1, 0.2, 'check set friction')
       contact:resetFriction()
-      test:assertEquals(2, math.floor(contact:getFriction()*10), 'check reset friction')
+      test:assertRange(contact:getFriction(), 0.2, 0.3, 'check reset friction')
+
+      -- check restitution
       test:assertEquals(0, contact:getRestitution(), 'check def restitution')
       contact:setRestitution(1)
       test:assertEquals(1, contact:getRestitution(), 'check set restitution')
       contact:resetRestitution()
       test:assertEquals(0, contact:getRestitution(), 'check reset restitution')
       pass = pass + 1
+
     end, function() end, function(shape_a, shape_b, contact) 
       if pass > 2 then
         contact:setEnabled(false)
       end
     end, function() end
   )
+
+  -- check bodies collided
   world:update(1)
-  test:assertEquals(true, collided, 'check bodies collided')
+  test:assertTrue(collided, 'check bodies collided')
+
   -- update again for enabled check
   world:update(1)
   test:assertEquals(2, pass, 'check ran twice')
+
 end
 
 
 -- Joint (love.physics.newDistanceJoint)
 love.test.physics.Joint = function(test)
+
   -- make joint
   local world = love.physics.newWorld(1, 1, true)
   local body1 = love.physics.newBody(world, 10, 10, 'dynamic')
   local body2 = love.physics.newBody(world, 20, 20, 'dynamic')
   local joint = love.physics.newDistanceJoint(body1, body2, 10, 10, 20, 20, true)
   test:assertObject(joint)
-  -- check props
+
+  -- check type
   test:assertEquals('distance', joint:getType(), 'check joint type')
-  test:assertEquals(false, joint:isDestroyed(), 'check not destroyed')
+
+  -- check not destroyed
+  test:assertFalse(joint:isDestroyed(), 'check not destroyed')
+
+  -- check reaction props
   test:assertEquals(0, joint:getReactionForce(1), 'check reaction force')
   test:assertEquals(0, joint:getReactionTorque(1), 'check reaction torque')
+
+  -- check body pointer
   local b1, b2 = joint:getBodies()
   test:assertEquals(body1:getX(), b1:getX(), 'check body 1')
   test:assertEquals(body2:getX(), b2:getX(), 'check body 2')
+
+  -- check joint anchors
   local x1, y1, x2, y2 = joint:getAnchors()
-  test:assertEquals(10, math.floor(x1), 'check anchor x1')
-  test:assertEquals(10, math.floor(y1), 'check anchor y1')
-  test:assertEquals(20, math.floor(x2), 'check anchor x2')
-  test:assertEquals(20, math.floor(y2), 'check anchor y2')
-  test:assertEquals(true, joint:getCollideConnected(), 'check not colliding')
+  test:assertRange(x1, 10, 11, 'check anchor x1')
+  test:assertRange(y1, 10, 11, 'check anchor y1')
+  test:assertRange(x2, 20, 21, 'check anchor x2')
+  test:assertRange(y2, 20, 21, 'check anchor y2')
+  test:assertTrue(joint:getCollideConnected(), 'check not colliding')
+
   -- test userdata
   test:assertEquals(nil, joint:getUserData(), 'check no data by def')
   joint:setUserData('hello')
   test:assertEquals('hello', joint:getUserData(), 'check set userdata')
+
   -- destroy
   joint:destroy()
-  test:assertEquals(true, joint:isDestroyed(), 'check destroyed')
-end
+  test:assertTrue(joint:isDestroyed(), 'check destroyed')
 
-
---love.test.physics.Test1 = function(test)
---  local world = love.physics.newWorld(0, 0, false)
---  local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
---  local shape1 = love.physics.newRectangleShape(body1, 5, 5, 10, 10)
---  local tlx, tly, brx, bry = shape1:getBoundingBox(1)
---  print('position:', tlx, tly, brx, bry) -- (-0.3, -0.3, 10.3, 10.3)
---  test:assertEquals(true, shape1:testPoint(5, 5), 'check point 1') -- returns false
---end
+end
 
 
 -- Shape (love.physics.newCircleShape)
 -- @NOTE in 12.0 fixtures have been merged into shapes
 love.test.physics.Shape = function(test)
+
   -- create shape
   local world = love.physics.newWorld(0, 0, false)
   local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
   local shape1 = love.physics.newRectangleShape(body1, 5, 5, 10, 10)
   test:assertObject(shape1)
-  -- check base properties
+
+  -- check child count
   test:assertEquals(1, shape1:getChildCount(), 'check child count')
-  test:assertEquals(0, math.floor(shape1:getRadius()), 'check radius')
+
+  -- check radius
+  test:assertRange(shape1:getRadius(), 0, 0.4, 'check radius')
+
+  -- check type match
   test:assertEquals('polygon', shape1:getType(), 'check rectangle type')
+
+  -- check body pointer
   test:assertEquals(0, shape1:getBody():getX(), 'check body link')
+
+  -- check category 
   test:assertEquals(1, shape1:getCategory(), 'check def category')
   shape1:setCategory(3, 5, 6)
   local categories = {shape1:getCategory()}
   test:assertEquals(14, categories[1] + categories[2] + categories[3], 'check set category')
-  test:assertEquals(false, shape1:isSensor(), 'check sensor def')
+
+  -- check sensor prop
+  test:assertFalse(shape1:isSensor(), 'check sensor def')
   shape1:setSensor(true)
-  test:assertEquals(true, shape1:isSensor(), 'check set sensor')
+  test:assertTrue(shape1:isSensor(), 'check set sensor')
   shape1:setSensor(false)
-  test:assertEquals(false, shape1:isDestroyed(), 'check not destroyed')
+
+  -- check not destroyed
+  test:assertFalse(shape1:isDestroyed(), 'check not destroyed')
+
+  -- check user data
   test:assertEquals(nil, shape1:getUserData(), 'check no user data')
   shape1:setUserData({ test = 14 })
   test:assertEquals(14, shape1:getUserData().test, 'check user data set')
+
   -- check bounding box
   -- polygons have an additional skin radius to help with collisions
   -- so this wont be 0, 0, 10, 10 as you'd think but has an additional 0.3 padding
@@ -290,41 +387,53 @@ love.test.physics.Shape = function(test)
   test:assertEquals(bottomRightX, brx, 'check bbox methods match brx')
   test:assertEquals(bottomRightY, bry, 'check bbox methods match bry')
   test:assertEquals(topLeftX, topLeftY, 'check bbox tl 1')
-  test:assertEquals(-3, math.floor(topLeftY*10), 'check bbox tl 2')
+  test:assertRange(topLeftY, -0.3, -0.2, 'check bbox tl 2')
   test:assertEquals(bottomRightX, bottomRightY, 'check bbox br 1')
-  test:assertEquals(10, math.floor(bottomRightX), 'check bbox br 2')
-  -- check physics props
+  test:assertRange(bottomRightX, 10.3, 10.4, 'check bbox br 2')
+
+  -- check density
   test:assertEquals(1, shape1:getDensity(), 'check def density')
   shape1:setDensity(5)
   test:assertEquals(5, shape1:getDensity(), 'check set density')
-  local x, y, mass, inertia = shape1:getMassData()
-  test:assertEquals(5, math.floor(x), 'check shape mass pos x')
-  test:assertEquals(5, math.floor(y), 'check shape mass pos y')
-  test:assertEquals(5, math.floor(mass*10), 'check mass at 1 density')
-  test:assertEquals(0, math.floor(inertia*10), 'check intertia at 1 density')
-  x, y, mass, inertia = shape1:computeMass(1000)
-  test:assertEquals(111, math.floor(mass), 'check mass at 1000 density')
-  test:assertEquals(7407, math.floor(inertia), 'check intertia at 1000 density')
-  test:assertEquals(2, math.floor(shape1:getFriction()*10), 'check def friction')
+
+  -- check mass
+  local x1, y1, mass1, inertia1 = shape1:getMassData()
+  test:assertRange(x1, 5, 5.1, 'check shape mass pos x')
+  test:assertRange(y1, 5, 5.1, 'check shape mass pos y')
+  test:assertRange(mass1, 0.5, 0.6, 'check mass at 1 density')
+  test:assertRange(inertia1, 0, 0.1, 'check intertia at 1 density')
+  local x2, y2, mass2, inertia2 = shape1:computeMass(1000)
+  test:assertRange(mass2, 111, 112, 'check mass at 1000 density')
+  test:assertRange(inertia2, 7407, 7408, 'check intertia at 1000 density')
+
+  -- check friction
+  test:assertRange(shape1:getFriction(), 0.2, 0.3, 'check def friction')
   shape1:setFriction(1)
   test:assertEquals(1, shape1:getFriction(), 'check set friction')
+
+  -- check restitution
   test:assertEquals(0, shape1:getRestitution(), 'check def restitution')
   shape1:setRestitution(0.5)
-  test:assertEquals(5, math.floor(shape1:getRestitution()*10), 'check set restitution')
+  test:assertRange(shape1:getRestitution(), 0.5, 0.6, 'check set restitution')
+
   -- check points
-  local shape2 = love.physics.newRectangleShape(body1, 5, 5, 10, 10)
+  local bodyp = love.physics.newBody(world, 0, 0, 'dynamic')
+  local shape2 = love.physics.newRectangleShape(bodyp, 5, 5, 10, 10)
   tlx, tly, brx, bry = shape2:getBoundingBox(1)
-  test:assertEquals(true, shape2:testPoint(5, 5), 'check point 5,5')
-  test:assertEquals(true, shape2:testPoint(15, 15, 10, 10, 0), 'check point 15,15 after translate 10,10')
-  test:assertEquals(true, shape2:testPoint(15, 15, 10, 10, 90), 'check point 15,15 after translate 10,10,90')
-  test:assertEquals(false, shape2:testPoint(5, 5, 10, 10, 90), 'check point 5,5 after translate 10,10,90')
-  test:assertEquals(false, shape2:testPoint(15, 15), 'check point 15,15')
-  local xn, yn, fraction = shape2:rayCast(-20, -20, 20, 20, 100, 0, 0, 0, 1)
-  test:assertNotEquals(nil, xn, 'check ray 1 x')
-  test:assertNotEquals(nil, xn, 'check ray 1 y')
-  xn, yn, fraction = shape2:rayCast(10, 10, -150, -150, 100, 0, 0, 0, 1)
-  test:assertEquals(nil, xn, 'check ray 2 x')
-  test:assertEquals(nil, xn, 'check ray 2 y')
+  test:assertTrue(shape2:testPoint(5, 5), 'check point 5,5')
+  test:assertTrue(shape2:testPoint(10, 10, 0, 15, 15), 'check point 15,15 after translate 10,10')
+  test:assertFalse(shape2:testPoint(5, 5, 90, 10, 10), 'check point 10,10 after translate 5,5,90')
+  test:assertFalse(shape2:testPoint(10, 10, 90, 5, 5), 'check point 5,5 after translate 10,10,90')
+  test:assertFalse(shape2:testPoint(15, 15), 'check point 15,15')
+
+  -- check ray cast
+  local xn1, yn1, fraction1 = shape2:rayCast(-20, -20, 20, 20, 100, 0, 0, 0, 1)
+  test:assertNotEquals(nil, xn1, 'check ray 1 x')
+  test:assertNotEquals(nil, xn1, 'check ray 1 y')
+  local xn2, yn2, fraction2 = shape2:rayCast(10, 10, -150, -150, 100, 0, 0, 0, 1)
+  test:assertEquals(nil, xn2, 'check ray 2 x')
+  test:assertEquals(nil, yn2, 'check ray 2 y')
+
   -- check filtering
   test:assertEquals(nil, shape2:getMask(), 'check no mask')
   shape2:setMask(1, 2, 3)
@@ -336,10 +445,13 @@ love.test.physics.Shape = function(test)
   test:assertEquals(1, cat, 'check filter cat')
   test:assertEquals(65528, mask, 'check filter mask')
   test:assertEquals(-1, group, 'check filter group')
-  -- run some collision checks using filters
+
+  -- check destroyed
   shape1:destroy()
-  test:assertEquals(true, shape1:isDestroyed(), 'check destroyed')
+  test:assertTrue(shape1:isDestroyed(), 'check destroyed')
   shape2:destroy()
+
+  -- run some collision checks using filters, setup new shapes 
   local body2 = love.physics.newBody(world, 5, 5, 'dynamic')
   local shape3 = love.physics.newRectangleShape(body1, 0, 0, 10, 10)
   local shape4 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
@@ -350,54 +462,67 @@ love.test.physics.Shape = function(test)
     function() end,
     function() end
   )
-  -- same group will always collide if the group is positive or never collide if it's negative
+
+  -- same positive group do collide
   shape3:setGroupIndex(1)
   shape4:setGroupIndex(1)
   world:update(1)
   test:assertEquals(1, collisions, 'check positive group collide')
+
+  -- check negative group dont collide
   shape3:setGroupIndex(-1)
   shape4:setGroupIndex(-1)
   body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
   test:assertEquals(1, collisions, 'check negative group collide')
-  -- mask sets which categories this fixture should NOT collide with.
+
+  -- check masks do collide
   shape3:setGroupIndex(0)
   shape4:setGroupIndex(0)
   shape3:setCategory(2)
   shape4:setMask(3)
   body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
   test:assertEquals(2, collisions, 'check mask collide')
+
+  -- check masks not colliding
   shape3:setCategory(2)
   shape4:setMask(2, 4, 6)
   body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
   test:assertEquals(2, collisions, 'check mask not collide')
+
 end
 
 
 -- World (love.physics.newWorld)
 love.test.physics.World = function(test)
+
   -- create new world
   local world = love.physics.newWorld(0, 0, false)
   local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
   local rectangle1 = love.physics.newRectangleShape(body1, 0, 0, 10, 10)
   test:assertObject(world)
-  -- check defaults
+
+  -- check bodies in world
   test:assertEquals(1, #world:getBodies(), 'check 1 body')
   test:assertEquals(0, world:getBodies()[1]:getX(), 'check body prop x')
   test:assertEquals(0, world:getBodies()[1]:getY(), 'check body prop y')
-  world:translateOrigin(-10, -10)
-  test:assertEquals(10, math.floor(world:getBodies()[1]:getX()), 'check body prop change x')
-  test:assertEquals(10, math.floor(world:getBodies()[1]:getY()), 'check body prop change y')
+  world:translateOrigin(-10, -10) -- check affects bodies
+  test:assertRange(world:getBodies()[1]:getX(), 9, 11, 'check body prop change x')
+  test:assertRange(world:getBodies()[1]:getY(), 9, 11, 'check body prop change y')
   test:assertEquals(1, world:getBodyCount(), 'check 1 body count')
-  test:assertEquals(false, world:isDestroyed(), 'check not destroyed')
-  test:assertEquals(false, world:isLocked(), 'check not updating')
+
+  -- check world status
+  test:assertFalse(world:isLocked(), 'check not updating')
+  test:assertFalse(world:isSleepingAllowed(), 'check no sleep (till brooklyn)')
+  world:setSleepingAllowed(true)
+  test:assertTrue(world:isSleepingAllowed(), 'check can sleep')
+
+  -- check world objects
   test:assertEquals(0, #world:getJoints(), 'check no joints')
   test:assertEquals(0, world:getJointCount(), 'check no joints count')
   test:assertEquals(0, world:getGravity(), 'check def gravity')
   test:assertEquals(0, #world:getContacts(), 'check no contacts')
   test:assertEquals(0, world:getContactCount(), 'check no contact count')
-  test:assertEquals(false, world:isSleepingAllowed(), 'check no sleep (till brooklyn)')
-  world:setSleepingAllowed(true)
-  test:assertEquals(true, world:isSleepingAllowed(), 'check can sleep')
+
   -- check callbacks are called
   local beginContact, endContact, preSolve, postSolve = world:getCallbacks()
   test:assertEquals(nil, beginContact, 'check no begin contact callback')
@@ -415,27 +540,33 @@ love.test.physics.World = function(test)
     function() preSolveCheck = true end,
     function() postSolveCheck = true end
   )
+
+  -- setup so we can collide stuff to call the callbacks
   local body2 = love.physics.newBody(world, 10, 10, 'dynamic')
   local rectangle2 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
-  test:assertEquals(false, beginContactCheck, 'check world didnt update after adding body')
+  test:assertFalse(beginContactCheck, 'check world didnt update after adding body')
   world:update(1)
-  test:assertEquals(true, beginContactCheck, 'check contact start')
-  test:assertEquals(true, preSolveCheck, 'check pre solve')
-  test:assertEquals(true, postSolveCheck, 'check post solve')
+  test:assertTrue(beginContactCheck, 'check contact start')
+  test:assertTrue(preSolveCheck, 'check pre solve')
+  test:assertTrue(postSolveCheck, 'check post solve')
   body2:setPosition(100, 100)
   world:update(1)
-  test:assertEquals(true, endContactCheck, 'check contact end')
+  test:assertTrue(endContactCheck, 'check contact end')
+
   -- check point checking
   local shapes = 0
   world:queryShapesInArea(0, 0, 10, 10, function(x)
     shapes = shapes + 1
   end)
   test:assertEquals(1, shapes, 'check shapes in area')
+
+  -- check raycast
   world:rayCast(0, 0, 200, 200, function(x)
     shapes = shapes + 1
     return 1
   end)
   test:assertEquals(3, shapes, 'check shapes in raycast')
+
   -- change collision logic
   test:assertEquals(nil, world:getContactFilter(), 'check def filter')
   world:update(1)
@@ -445,11 +576,16 @@ love.test.physics.World = function(test)
   body2:setPosition(10, 10)
   world:update(1)
   test:assertEquals(1, collisions, 'check collision logic change')
-  -- final bits
+
+  -- check gravity
   world:setGravity(1, 1)
   test:assertEquals(1, world:getGravity(), 'check grav change')
+
+  -- check destruction
+  test:assertFalse(world:isDestroyed(), 'check not destroyed')
   world:destroy()
-  test:assertEquals(true, world:isDestroyed(), 'check world destroyed')
+  test:assertTrue(world:isDestroyed(), 'check world destroyed')
+
 end
 
 
@@ -468,7 +604,7 @@ love.test.physics.getDistance = function(test)
   local shape1 = love.physics.newEdgeShape(body, 0, 0, 5, 5)
   local shape2 = love.physics.newEdgeShape(body, 10, 10, 15, 15)
   -- check distance between them
-  test:assertEquals(647106, math.floor(love.physics.getDistance(shape1, shape2)*100000), 'check distance matches')
+  test:assertRange(love.physics.getDistance(shape1, shape2), 6, 7, 'check distance matches')
 end
 
 

+ 32 - 8
testing/tests/sound.lua

@@ -10,52 +10,76 @@
 
 -- Decoder (love.sound.newDecoder)
 love.test.sound.Decoder = function(test)
+
   -- create obj
   local decoder = love.sound.newDecoder('resources/click.ogg')
   test:assertObject(decoder)
-  -- check decoder props
+
+  -- check bit depth
   test:assertMatch({8, 16}, decoder:getBitDepth(), 'check bit depth')
+
+  -- check channel count
   test:assertMatch({1, 2}, decoder:getChannelCount(), 'check channel count')
-  test:assertEquals(66, math.floor(decoder:getDuration()*1000), 'check duration')
+
+  -- check duration
+  test:assertRange(decoder:getDuration(), 0.06, 0.07, 'check duration')
+
+  -- check sample rate
   test:assertEquals(44100, decoder:getSampleRate(), 'check sample rate')
+
   -- check makes sound data (test in method below)
   test:assertObject(decoder:decode())
+
   -- check cloning sound
   local clone = decoder:clone()
   test:assertMatch({8, 16}, clone:getBitDepth(), 'check cloned bit depth')
   test:assertMatch({1, 2}, clone:getChannelCount(), 'check cloned channel count')
-  test:assertEquals(66, math.floor(clone:getDuration()*1000), 'check cloned duration')
+  test:assertRange(clone:getDuration(), 0.06, 0.07, 'check cloned duration')
   test:assertEquals(44100, clone:getSampleRate(), 'check cloned sample rate')
+
 end
 
 
 -- SoundData (love.sound.newSoundData)
 love.test.sound.SoundData = function(test)
+
   -- create obj
   local sdata = love.sound.newSoundData('resources/click.ogg')
   test:assertObject(sdata)
-  -- check data props
+
+  -- check data size + string
   test:assertEquals(11708, sdata:getSize(), 'check size')
   test:assertNotNil(sdata:getString())
+
+  -- check bit depth
   test:assertMatch({8, 16}, sdata:getBitDepth(), 'check bit depth')
+
+  -- check channel count
   test:assertMatch({1, 2}, sdata:getChannelCount(), 'check channel count')
-  test:assertEquals(66, math.floor(sdata:getDuration()*1000), 'check duration')
+
+  -- check duration
+  test:assertRange(sdata:getDuration(), 0.06, 0.07, 'check duration')
+
+  -- check samples
   test:assertEquals(44100, sdata:getSampleRate(), 'check sample rate')
   test:assertEquals(2927, sdata:getSampleCount(), 'check sample count')
+
   -- check cloning
   local clone = sdata:clone()
   test:assertEquals(11708, clone:getSize(), 'check clone size')
   test:assertNotNil(clone:getString())
   test:assertMatch({8, 16}, clone:getBitDepth(), 'check clone bit depth')
   test:assertMatch({1, 2}, clone:getChannelCount(), 'check clone channel count')
-  test:assertEquals(66, math.floor(clone:getDuration()*1000), 'check clone duration')
+  test:assertRange(clone:getDuration(), 0.06, 0.07, 'check clone duration')
   test:assertEquals(44100, clone:getSampleRate(), 'check clone sample rate')
   test:assertEquals(2927, clone:getSampleCount(), 'check clone sample count')
+
   -- check sample setting
-  test:assertEquals(-22, math.floor(sdata:getSample(0.001)*100000), 'check sample 1')
-  test:assertEquals(-22, math.floor(sdata:getSample(0.005)*100000), 'check sample 1')
+  test:assertRange(sdata:getSample(0.001), -0.1, 0, 'check sample 1')
+  test:assertRange(sdata:getSample(0.005), -0.1, 0, 'check sample 1')
   sdata:setSample(0.002, 1)
   test:assertEquals(1, sdata:getSample(0.002), 'check setting sample manually')
+
 end
 
 

+ 15 - 2
testing/tests/thread.lua

@@ -10,9 +10,11 @@
 
 -- Channel (love.thread.newChannel)
 love.test.thread.Channel = function(test)
+
   -- create channel
   local channel = love.thread.getChannel('test')
   test:assertObject(channel)
+
   -- setup thread to use
   local threadcode1 = [[
     require("love.timer")
@@ -23,6 +25,7 @@ love.test.thread.Channel = function(test)
   ]]
   local thread1 = love.thread.newThread(threadcode1)
   thread1:start()
+
   -- check message sent from thread to channel
   local msg1 = channel:demand()
   test:assertEquals('hello world', msg1, 'check 1st message was sent')
@@ -32,6 +35,7 @@ love.test.thread.Channel = function(test)
   local msg2 = channel:pop()
   test:assertEquals('me again', msg2, 'check 2nd message was sent')
   channel:clear()
+
   -- setup another thread for some ping pong
   local threadcode2 = [[
     local function setChannel(channel, value)
@@ -54,24 +58,30 @@ love.test.thread.Channel = function(test)
       end
     end
   ]]
+
   -- first we run a thread that will send 1 ping
   local thread2 = love.thread.newThread(threadcode2)
   thread2:start()
+
   -- we wait for that ping to be sent and then send a pong back
   local msg3 = channel:demand()
   test:assertEquals('ping', msg3, 'check message recieved 1')
+
   -- thread should be waiting for us, and checking is the ping was read
   channel:supply('pong', 1)
+
   -- if it was then it should send back our pong and thread should die
   thread2:wait()
   local msg4 = channel:pop()
   test:assertEquals('pong', msg4, 'check message recieved 2')
   test:assertEquals(0, channel:getCount())
+
 end
 
 
 -- Thread (love.thread.newThread)
 love.test.thread.Thread = function(test)
+
   -- create thread
   local threadcode = [[
     local b = 0
@@ -81,18 +91,21 @@ love.test.thread.Thread = function(test)
   ]]
   local thread = love.thread.newThread(threadcode)
   test:assertObject(thread)
+
   -- check thread runs
   thread:start()
-  test:assertEquals(true, thread:isRunning(), 'check started')
+  test:assertTrue(thread:isRunning(), 'check started')
   thread:wait()
-  test:assertEquals(false, thread:isRunning(), 'check finished')
+  test:assertFalse(thread:isRunning(), 'check finished')
   test:assertEquals(nil, thread:getError(), 'check no errors')
+
   -- check an invalid thread
   local badthreadcode = 'local b = 0\nreturn b + "string" .. 10'
   local badthread = love.thread.newThread(badthreadcode)
   badthread:start()
   badthread:wait()
   test:assertNotNil(badthread:getError())
+
 end
 
 

+ 2 - 2
testing/tests/timer.lua

@@ -33,7 +33,7 @@ love.test.timer.getTime = function(test)
   local starttime = love.timer.getTime()
   love.timer.sleep(1)
   local endtime = love.timer.getTime() - starttime
-  test:assertEquals(1, math.floor(endtime), 'check 1s passes')
+  test:assertRange(endtime, 0.9, 1.1, 'check 1s passes')
 end
 
 
@@ -41,7 +41,7 @@ end
 love.test.timer.sleep = function(test)
   local starttime = love.timer.getTime()
   love.timer.sleep(1)
-  test:assertEquals(1, math.floor(love.timer.getTime() - starttime), 'check 1s passes')
+  test:assertRange(love.timer.getTime() - starttime, 0.9, 1.1, 'check 1s passes')
 end
 
 

+ 9 - 5
testing/tests/video.lua

@@ -10,21 +10,25 @@
 
 -- VideoStream (love.thread.newVideoStream)
 love.test.video.VideoStream = function(test)
+
   -- create obj
   local video = love.video.newVideoStream('resources/sample.ogv')
   test:assertObject(video)
+
   -- check def properties
   test:assertEquals('resources/sample.ogv', video:getFilename(), 'check filename')
-  test:assertEquals(false, video:isPlaying(), 'check not playing by def')
-  -- check playing and pausing
+  test:assertFalse(video:isPlaying(), 'check not playing by def')
+
+  -- check playing and pausing states
   video:play()
-  test:assertEquals(true, video:isPlaying(), 'check now playing')
+  test:assertTrue(video:isPlaying(), 'check now playing')
   video:seek(0.3)
-  test:assertEquals(3, math.floor(video:tell()*10), 'check seek/tell')
+  test:assertRange(video:tell(), 0.3, 0.4, 'check seek/tell')
   video:rewind()
   test:assertEquals(0, video:tell(), 'check rewind')
   video:pause()
-  test:assertEquals(false, video:isPlaying(), 'check paused')
+  test:assertFalse(video:isPlaying(), 'check paused')
+
 end
 
 

+ 28 - 28
testing/tests/window.lua

@@ -13,10 +13,10 @@ love.test.window.close = function(test)
   -- closing window should cause graphics to not be active
   love.window.close()
   local active = love.graphics.isActive()
-  test:assertEquals(false, active, 'check window not active')
+  test:assertFalse(active, 'check window not active')
   love.window.updateMode(360, 240) -- reset
   active = love.graphics.isActive() 
-  test:assertEquals(true, active, 'check window active again')
+  test:assertTrue(active, 'check window active again')
 end
 
 -- love.window.fromPixels
@@ -68,10 +68,10 @@ end
 -- love.window.getFullscreen
 love.test.window.getFullscreen = function(test)
   -- check not fullscreen to start
-  test:assertEquals(false, love.window.getFullscreen(), 'check not fullscreen')
+  test:assertFalse(love.window.getFullscreen(), 'check not fullscreen')
   love.window.setFullscreen(true)
   -- check now fullscreen
-  test:assertEquals(true, love.window.getFullscreen(), 'check now fullscreen')
+  test:assertTrue(love.window.getFullscreen(), 'check now fullscreen')
   love.window.setFullscreen(false) -- reset
 end
 
@@ -100,7 +100,7 @@ love.test.window.getMode = function(test)
   local w, h, flags = love.window.getMode()
   test:assertEquals(360, w, 'check w')
   test:assertEquals(240, h, 'check h')
-  test:assertEquals(false, flags["fullscreen"], 'check fullscreen')
+  test:assertFalse(flags["fullscreen"], 'check fullscreen')
 end
 
 
@@ -159,20 +159,20 @@ love.test.window.isDisplaySleepEnabled = function(test)
   test:assertNotNil(love.window.isDisplaySleepEnabled())
   -- check disabled
   love.window.setDisplaySleepEnabled(false)
-  test:assertEquals(false, love.window.isDisplaySleepEnabled(), 'check sleep disabled')
+  test:assertFalse(love.window.isDisplaySleepEnabled(), 'check sleep disabled')
   -- check enabled
   love.window.setDisplaySleepEnabled(true)
-  test:assertEquals(true, love.window.isDisplaySleepEnabled(), 'check sleep enabled')
+  test:assertTrue(love.window.isDisplaySleepEnabled(), 'check sleep enabled')
 end
 
 
 -- love.window.isMaximized
 love.test.window.isMaximized = function(test)
-  test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
+  test:assertFalse(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')
+  test:assertTrue(love.window.isMaximized(), 'check window now maximized')
   love.window.restore()
 end
 
@@ -180,12 +180,12 @@ end
 -- love.window.isMinimized
 love.test.window.isMinimized = function(test)
   -- check not minimized to start
-  test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
+  test:assertFalse(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')
+  test:assertTrue(love.window.isMinimized(), 'check window minimized')
   love.window.restore()
 end
 
@@ -193,10 +193,10 @@ end
 -- love.window.isOpen
 love.test.window.isOpen = function(test)
   -- check open initially
-  test:assertEquals(true, love.window.isOpen(), 'check window open')
+  test:assertTrue(love.window.isOpen(), 'check window open')
   -- try closing
   love.window.close()
-  test:assertEquals(false, love.window.isOpen(), 'check window closed')
+  test:assertFalse(love.window.isOpen(), 'check window closed')
   love.window.updateMode(360, 240) -- reset 
 end
 
@@ -204,34 +204,34 @@ end
 -- love.window.isVisible
 love.test.window.isVisible = function(test)
   -- check visible initially
-  test:assertEquals(true, love.window.isVisible(), 'check window visible')
+  test:assertTrue(love.window.isVisible(), 'check window visible')
   -- check closing makes window not visible
   love.window.close()
-  test:assertEquals(false, love.window.isVisible(), 'check window not visible')
+  test:assertFalse(love.window.isVisible(), 'check window not visible')
   love.window.updateMode(360, 240) -- reset 
 end
 
 
 -- love.window.maximize
 love.test.window.maximize = function(test)
-  test:assertEquals(false, love.window.isMaximized(), 'check window not maximized')
+  test:assertFalse(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')
+  test:assertTrue(love.window.isMaximized(), 'check window maximized')
   love.window.restore()
 end
 
 
 -- love.window.minimize
 love.test.window.minimize = function(test)
-  test:assertEquals(false, love.window.isMinimized(), 'check window not minimized')
+  test:assertFalse(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')
+  test:assertTrue(love.window.isMinimized(), 'check window maximized')
   love.window.restore()
 end
 
@@ -250,7 +250,7 @@ love.test.window.restore = function(test)
   love.window.restore()
   test:waitFrames(10)
   -- check restoring the state of the window
-  test:assertEquals(false, love.window.isMinimized(), 'check window restored')
+  test:assertFalse(love.window.isMinimized(), 'check window restored')
 end
 
 
@@ -258,10 +258,10 @@ end
 love.test.window.setDisplaySleepEnabled = function(test)
   -- check disabling sleep
   love.window.setDisplaySleepEnabled(false)
-  test:assertEquals(false, love.window.isDisplaySleepEnabled(), 'check sleep disabled')
+  test:assertFalse(love.window.isDisplaySleepEnabled(), 'check sleep disabled')
   -- check setting it back to enabled
   love.window.setDisplaySleepEnabled(true)
-  test:assertEquals(true, love.window.isDisplaySleepEnabled(), 'check sleep enabled')
+  test:assertTrue(love.window.isDisplaySleepEnabled(), 'check sleep enabled')
 end
 
 
@@ -269,10 +269,10 @@ end
 love.test.window.setFullscreen = function(test)
   -- check fullscreen is set
   love.window.setFullscreen(true)
-  test:assertEquals(true, love.window.getFullscreen(), 'check fullscreen')
+  test:assertTrue(love.window.getFullscreen(), 'check fullscreen')
   -- check setting back to normal
   love.window.setFullscreen(false)
-  test:assertEquals(false, love.window.getFullscreen(), 'check not fullscreen')
+  test:assertFalse(love.window.getFullscreen(), 'check not fullscreen')
 end
 
 
@@ -298,8 +298,8 @@ love.test.window.setMode = function(test)
   local width, height, flags = love.window.getMode()
   test:assertEquals(512, width, 'check window w match')
   test:assertEquals(512, height, 'check window h match')
-  test:assertEquals(false, flags["fullscreen"], 'check window not fullscreen')
-  test:assertEquals(false, flags["resizable"], 'check window not resizeable')
+  test:assertFalse(flags["fullscreen"], 'check window not fullscreen')
+  test:assertFalse(flags["resizable"], 'check window not resizeable')
   love.window.setMode(360, 240, {
     fullscreen = false,
     resizable = true
@@ -362,8 +362,8 @@ love.test.window.updateMode = function(test)
   local width, height, flags = love.window.getMode()
   test:assertEquals(360, width, 'check window w match')
   test:assertEquals(240, height, 'check window h match')
-  test:assertEquals(false, flags["fullscreen"], 'check window not fullscreen')
-  test:assertEquals(false, flags["resizable"], 'check window not resizeable')
+  test:assertFalse(flags["fullscreen"], 'check window not fullscreen')
+  test:assertFalse(flags["resizable"], 'check window not resizeable')
   love.window.setMode(360, 240, { -- reset
     fullscreen = false,
     resizable = true

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