gear/spec/gear_spec.lua

217 lines
7.2 KiB
Lua

require 'busted.runner'()
describe("gear", function()
setup(function()
gear = require 'init'
algo = gear.algo
rect = gear.rect
math = require 'math'
end)
describe("insertion sort #sort", function()
local insertionsort = algo.insertionsort
it("sorts arrays", function()
local elems = {}
local expect = {}
for n = 2,512 do
for i = 1,n do
elems[i] = math.random(-32768, 32767)
expect[i] = elems[i]
end
table.sort(expect)
insertionsort(elems)
assert.are.same(expect, elems)
end
end)
it("has no effect on single element array", function()
for i = 1,10 do
local val = (math.random() - 0.5) * 1024
local expect = { val }
local elems = { val }
insertionsort(elems)
assert.are.same(expect, elems)
end
end)
it("does nothing on empty array", function()
local expect = {}
local elems = {}
insertionsort(elems)
assert.are.same(expect, elems)
end)
end)
describe("binary search #bsearch", function()
local bsearchl = algo.bsearchl
local bsearchr = algo.bsearchr
it("behaves properly on empty arrays", function()
local empty = {}
local idx = bsearchr(empty, 1)
assert.is_true(empty[idx] == nil)
idx = bsearchl(empty, 1)
assert.is_true(empty[idx] == nil)
end)
it("finds elements within sorted arrays", function()
local dims = { 1, 2, 64, 512, 1024 }
for _,n in ipairs(dims) do
local elems = {}
for i = 1,n do
elems[#elems+1] = ((math.random() - 0.5) * 4096)
end
local mustfind = {}
for i = 1,10 do
mustfind[#mustfind+1] = elems[math.random(1,#elems)]
end
local mustnotfind = {
4097,
-4097,
-math.huge,
math.huge,
16386,
-16386
}
table.sort(elems)
for _,v in ipairs(mustfind) do
local idx = bsearchl(elems, v)
assert.equal(v, elems[idx])
assert.is_false(elems[idx+1] ~= nil and elems[idx+1] <= v)
idx = bsearchr(elems, v)
assert.equal(v, elems[idx])
assert.is_false(elems[idx+1] ~= nil and elems[idx+1] <= v)
end
for _,v in ipairs(mustnotfind) do
local idx = bsearchl(elems, v)
assert.not_equal(v, elems[idx])
if v < elems[1] then
assert.is_true(elems[idx] == nil)
else
assert.is_true(elems[idx] <= v)
end
idx = bsearchr(elems, v)
assert.not_equal(v, elems[idx])
if v > elems[#elems] then
assert.is_true(elems[idx] == nil)
else
assert.is_true(elems[idx] >= v)
end
end
end
end)
end)
describe("rect #bounds", function()
local bigreal = 9999999.0
local min,max = math.min, math.max
local pointinrect = rect.pointinside
local rectempty = rect.isempty
local recteq = rect.eq
local rectexpand = rect.expand
local rectinside = rect.rectinside
local rectintersection = rect.intersection
local rectunion = rect.union
it("is empty if its dimensions are negative", function()
assert.is_true(rectempty(0,0,-1,-1))
assert.is_true(rectempty(bigreal,bigreal,-bigreal,-bigreal))
assert.is_true(rectempty(-bigreal,-bigreal,-bigreal,-bigreal))
assert.is_true(rectempty(0,0,bigreal,-1))
assert.is_true(rectempty(0,0,0,-1))
assert.is_true(rectempty(0,0,-1,bigreal))
assert.is_true(rectempty(0,0,-1,0))
assert.is_false(rectempty(0,0,0,0))
assert.is_false(rectempty(0,0,-0,0))
assert.is_false(rectempty(bigreal,bigreal,bigreal,bigreal))
end)
it("doesn't contain anything if empty", function()
local x,y,w,h = 0,0,-1,-1
assert.is_false(rectinside(0,0,0,0, x,y,w,h))
assert.is_false(rectinside(x,y,w,h, x,y,w,h))
assert.is_false(rectinside(0,0,bigreal,bigreal, x,y,w,h))
assert.is_false(rectinside(0,0,-bigreal,-bigreal, x,y,w,h))
end)
it("always contains empty rect if non-empty", function()
assert.is_true(rectinside(0,0,-1,-1, 0,0,0,0))
assert.is_true(rectinside(bigreal,bigreal,-bigreal,-bigreal, 0,0,0,0))
assert.is_true(rectinside(bigreal,bigreal,bigreal,-bigreal, 0,0,0,0))
assert.is_true(rectinside(bigreal,bigreal,-bigreal,bigreal, 0,0,0,0))
assert.is_true(rectinside(bigreal,bigreal,-1.0e-5,bigreal, 0,0,0,0))
end)
it("may contain a single point", function()
for i,pt in ipairs({{0,0}, {bigreal,bigreal}, {-bigreal,-bigreal}}) do
local px,py = pt[1], pt[2]
local x,y,w,h = 0,0,-1,-1
x,y,w,h = rectexpand(x,y,w,h, px,py)
assert.is_false(rectempty(x,y,w,h))
assert.is_true(pointinrect(px,py, x,y,w,h))
assert.is_true(recteq(x,y,w,h, px,py,0,0))
end
end)
it("may expand arbitrarily to contain more points", function()
local points = {}
local xmin,ymin = math.huge, math.huge
local xmax,ymax = -math.huge,-math.huge
for i = 1,16535 do
local x = (math.random() - 0.5) * 50
local y = (math.random() - 0.5) * 50
points[#points+1] = { x, y }
xmin = min(xmin, x)
ymin = min(ymin, y)
xmax = max(xmax, x)
ymax = max(ymax, y)
end
local x,y,w,h = 0,0,-1,-1
for i,pt in ipairs(points) do
local px,py = pt[1], pt[2]
x,y,w,h = rectexpand(x,y,w,h, px,py)
assert.is_true(pointinrect(px,py, x,y,w,h))
end
local ex,ey,ew,eh = xmin,ymin, xmax-xmin,ymax-ymin
assert.is_false(rectempty(x,y,w,h))
assert.is_true(recteq(x,y,w,h, ex,ey,ew,eh, 0.1))
end)
it("may expand arbitrarily to contain more rects", function()
pending("to be tested...")
end)
it("may be used to enclose arbitrary geometry", function()
pending("to be tested...")
end)
it("may be tested against other rects", function()
pending("to be tested...")
end)
it("may be intersected with other rects", function()
pending("to be tested...")
end)
end)
end)