217 lines
7.2 KiB
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)
|