You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
8.7 KiB
362 lines
8.7 KiB
dofile("wow_api.lua")
|
|
dofile("LibStub.lua")
|
|
dofile("../CallbackHandler-1.0/CallbackHandler-1.0.lua")
|
|
|
|
local CH = assert(LibStub("CallbackHandler-1.0"))
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- test default names
|
|
do
|
|
local test = {}
|
|
CH:New(test, nil, nil, nil)
|
|
|
|
assert(test.RegisterCallback)
|
|
assert(test.UnregisterCallback)
|
|
assert(test.UnregisterAllCallbacks)
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- test custom names
|
|
do
|
|
local test = {}
|
|
CH:New(test, "Reg", "Unreg", "UnregAll")
|
|
|
|
assert(test.Reg)
|
|
assert(test.Unreg)
|
|
assert(test.UnregAll)
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- test with unregall==false
|
|
do
|
|
local test = {}
|
|
CH:New(test, "Reg", "Unreg", false)
|
|
|
|
assert(test.Reg)
|
|
assert(test.Unreg)
|
|
assert(test.UnregisterAllCallbacks == nil)
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- test OnUsed / OnUnused
|
|
do
|
|
local test = {}
|
|
|
|
local n=0
|
|
|
|
local reg = CH:New(test, "Reg", "Unreg", "UnregAll")
|
|
|
|
local lastOnUsed
|
|
function reg:OnUsed(target, event)
|
|
assert(self==reg)
|
|
assert(target==test)
|
|
lastOnUsed=event
|
|
n=n+1
|
|
end
|
|
|
|
local lastOnUnused
|
|
function reg:OnUnused(target, event)
|
|
assert(self==reg)
|
|
assert(target==test)
|
|
lastOnUnused=event
|
|
n=n+1
|
|
end
|
|
|
|
|
|
local function func() end
|
|
|
|
test.Reg("addon1", "Thing1", func) -- should fire an OnUsed Thing1
|
|
assert(n==1 and lastOnUsed=="Thing1")
|
|
|
|
test.Reg("addon1", "Thing2", func) -- should fire an OnUsed Thing2
|
|
assert(n==2 and lastOnUsed=="Thing2")
|
|
|
|
test.Reg("addon1", "Thing1", func) -- should NOT fire an OnUsed (Thing1 seen already)
|
|
assert(n==2)
|
|
|
|
test.Reg("addon2", "Thing1", func) -- should NEITHER fire an OnUsed (Thing1 seen already)
|
|
assert(n==2)
|
|
|
|
test.Reg("addon2", "Thing2", func) -- should NEITHER fire an OnUsed (Thing2 seen already)
|
|
assert(n==2)
|
|
|
|
-- now start unregging Thing1
|
|
|
|
test.Unreg("addon1", "Thing1") -- Still one left, shouldnt fire OnUnused yet
|
|
assert(n==2)
|
|
|
|
test.Unreg("addon2", "Thing1")
|
|
assert(n==3 and lastOnUnused=="Thing1", dump(n,lastOnUnused)) -- Now we should get OnUnused Thing1
|
|
|
|
-- aaand unreg Thing2 (via some UnregAlls)
|
|
|
|
test.UnregAll("addon1")
|
|
assert(n==3)
|
|
test.UnregAll("addon2")
|
|
assert(n==4 and lastOnUnused=="Thing2")
|
|
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- ACE-67: Test registering new handlers for an event while in a callback for that event
|
|
--
|
|
-- Problem: for k,v in pairs(eventlist) eventlist[somethingnew]=foo end
|
|
-- This happens when we fire callback X, and the handler registers another handler for X
|
|
|
|
do
|
|
local test={}
|
|
local reg = CH:New(test, "Reg", "Unreg", "UnregAll")
|
|
local REPEATS = 1000 -- we get roughly 50% failure ratio, so 1000 tests WILL trigger it
|
|
|
|
local hasRun = {}
|
|
local hasRunNoops = {}
|
|
|
|
local function noop(noopName)
|
|
hasRunNoops[noopName]=hasRunNoops[noopName]+1
|
|
end
|
|
|
|
local rnd=math.random
|
|
|
|
local regMore=true
|
|
local function RegOne(name)
|
|
hasRun[name]=hasRun[name]+1
|
|
if regMore then
|
|
local noopName
|
|
repeat
|
|
noopName = tostring(rnd(1,99999999))
|
|
until not hasRunNoops[noopName] and not hasRun[noopName]
|
|
hasRunNoops[noopName]=0
|
|
test.Reg(noopName, "EVENT", noop, noopName)
|
|
end
|
|
end
|
|
|
|
for i=1,REPEATS do
|
|
local name
|
|
repeat
|
|
name=tostring(rnd(1,99999999))
|
|
until not hasRun[name]
|
|
hasRun[name]=0
|
|
test.Reg(name, "EVENT", RegOne, name)
|
|
end
|
|
|
|
-- Firing this event should lead to all 1000 callbacks running, and registering another 1000 callbacks
|
|
reg:Fire("EVENT")
|
|
|
|
-- Test that they all ran once
|
|
local n=0
|
|
for k,v in pairs(hasRun) do
|
|
assert(v==1, dump(k,v).." should be ==1")
|
|
n=n+1
|
|
end
|
|
assert(n==REPEATS, dump(n))
|
|
|
|
-- And that all the noops didnt run (they should have been delayed til the next fire)
|
|
local n=0
|
|
for k,v in pairs(hasRunNoops) do
|
|
assert(v==0, dump(k,v).." should be ==0")
|
|
n=n+1
|
|
end
|
|
assert(n==REPEATS, dump(n))
|
|
|
|
|
|
-- Now we run all of them again without registering more, so we should get 1000+1000 callbacks
|
|
regMore=false
|
|
reg:Fire("EVENT")
|
|
|
|
-- Test that all main events ran another time (total 2)
|
|
local n=0
|
|
for k,v in pairs(hasRun) do
|
|
assert(v==2, dump(k,v).." should be ==2")
|
|
n=n+1
|
|
end
|
|
assert(n==REPEATS, dump(n))
|
|
|
|
-- And that all the noops ran once
|
|
local n=0
|
|
for k,v in pairs(hasRunNoops) do
|
|
assert(v==1, dump(k,v).." should be ==1")
|
|
n=n+1
|
|
end
|
|
assert(n==REPEATS, dump(n))
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- ACE-67: Test reentrancy (firing an event from inside a callback) PLUS regging more callbacks from inside them!
|
|
|
|
for REPEATS=1,20 do
|
|
local test={}
|
|
local reg = CH:New(test, "Reg", "Unreg", "UnregAll")
|
|
|
|
local fires=0
|
|
local extraFires=0
|
|
|
|
local function extrahandler()
|
|
extraFires = extraFires+1
|
|
end
|
|
|
|
local function handler(n, event, arg)
|
|
fires=fires+1
|
|
assert(reg.recurse==arg, dump(reg.recurse, arg)) -- check up that the internal recursion counter is tracking correctly
|
|
|
|
-- to make things even more interesting, we'll reg even more callbacks recursively (a lot of these should be overwrites)
|
|
test.Reg("extra"..n..","..arg, "EVENT", extrahandler)
|
|
|
|
if arg==n then
|
|
reg:Fire("EVENT", arg+1) -- we'll end up with up to REPEATS levels of recursion
|
|
end
|
|
end
|
|
|
|
for n=1,REPEATS do
|
|
test.Reg("handler"..n, "EVENT", handler, n)
|
|
end
|
|
|
|
-- Fire the event!
|
|
assert(reg.recurse==0)
|
|
reg:Fire("EVENT", 1)
|
|
assert(reg.recurse==0)
|
|
|
|
assert(fires == REPEATS + (REPEATS*REPEATS), dump(fires, REPEATS + (REPEATS*REPEATS), REPEATS))
|
|
assert(extraFires==0)
|
|
|
|
-- Fire again! This time we should see extraFires
|
|
fires=0
|
|
assert(reg.recurse==0)
|
|
reg:Fire("EVENT", 1)
|
|
assert(reg.recurse==0)
|
|
|
|
assert(fires == REPEATS + (REPEATS*REPEATS), dump(fires, REPEATS + (REPEATS*REPEATS), REPEATS))
|
|
assert(extraFires== fires + fires*REPEATS)
|
|
|
|
end
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- ACE-67: Test that a recursively registered callback is properly removed
|
|
|
|
for REPEATS=1,20 do
|
|
local test={}
|
|
local reg = CH:New(test, "Reg", "Unreg", "UnregAll")
|
|
|
|
local extraFired=0
|
|
local function extra()
|
|
extraFired=extraFired+1
|
|
end
|
|
|
|
local fired=0
|
|
local function RegExtra()
|
|
fired = fired + 1
|
|
|
|
local name=tostring(math.random(1,999999))
|
|
test.Reg(name,"EVENT",extra)
|
|
if fired==1 then
|
|
test.Unreg(name,"EVENT") -- #1: test single unreg
|
|
elseif fired==2 then
|
|
test.UnregAll(name) -- #2: test unregall
|
|
elseif fired==3 then
|
|
-- let it be regged
|
|
end
|
|
end
|
|
|
|
test.Reg("test","EVENT",RegExtra)
|
|
|
|
reg:Fire("EVENT")
|
|
assert(fired==1)
|
|
assert(extraFired==0, dump(extraFired))
|
|
|
|
reg:Fire("EVENT")
|
|
assert(fired==2)
|
|
assert(extraFired==0, dump(extraFired))
|
|
|
|
reg:Fire("EVENT")
|
|
assert(fired==3)
|
|
assert(extraFired==0, dump(extraFired)) -- there's an extra regged, but it hasn't fired yet
|
|
|
|
reg:Fire("EVENT")
|
|
assert(fired==4)
|
|
assert(extraFired==1, dump(extraFired)) -- yeah ok now it fired
|
|
|
|
end
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------
|
|
-- Delayed registration:
|
|
-- - Verify that delayed OnUsed are fired
|
|
-- - Verify that OnUnused aren't fired if OnUsed hasn't been fired yet
|
|
|
|
do
|
|
local obj = {}
|
|
local reg = CH:New(obj, "Reg", "Unreg", "UnregAll")
|
|
|
|
local dummys, regs, onused, onunused = 0,0,0,0
|
|
|
|
local addon = {}
|
|
addon.Dummy = function() dummys=dummys+1 end
|
|
addon.ReggingEvent = function() end
|
|
obj.Reg(addon,"ReggingEvent")
|
|
|
|
reg.OnUsed = function(reg,tgt,evt)
|
|
assert(evt=="Dummy")
|
|
onused = onused + 1
|
|
end
|
|
reg.OnUnused = function(rev,tgt,evt)
|
|
assert(evt=="Dummy")
|
|
onunused = onunused + 1
|
|
end
|
|
|
|
-- Register "Dummy" from inside "ReggingEvent"
|
|
addon.ReggingEvent = function()
|
|
regs=regs+1
|
|
obj.Reg(addon,"Dummy")
|
|
assert(onused==0) -- shouldn't fire yet
|
|
end
|
|
|
|
reg:Fire("ReggingEvent")
|
|
assert(regs==1) -- should have run once
|
|
assert(onused==1) -- should have fired now
|
|
assert(dummys==0)
|
|
reg:Fire("Dummy")
|
|
assert(dummys==1)
|
|
assert(onunused==0)
|
|
|
|
-- Now unregister "Dummy" normally
|
|
obj.Unreg(addon,"Dummy")
|
|
assert(onunused==1)
|
|
reg:Fire("Dummy") -- sanity: should do nothing unless something is SERIOUSLY broken
|
|
assert(dummys==1)
|
|
|
|
|
|
-- Register "Dummy" from inside "ReggingEvent" and then unregister it
|
|
dummys, regs, onused, onunused = 0,0,0,0
|
|
addon.ReggingEvent = function() -- This event tries to register more events inside it
|
|
regs=regs+1
|
|
obj.Reg(addon,"Dummy")
|
|
assert(onused==0) -- shouldn't fire yet
|
|
reg:Fire("Dummy") -- this shouldn't fire; it should still be queued
|
|
obj.Unreg(addon,"Dummy")
|
|
assert(onunused==0) -- shouldn't fire at all now since onused never did
|
|
end
|
|
|
|
reg:Fire("ReggingEvent")
|
|
assert(regs==1)
|
|
assert(dummys==0)
|
|
|
|
reg:Fire("Dummy") -- sanity: should do nothing unless something is SERIOUSLY broken
|
|
assert(onused==0)
|
|
assert(onunused==0)
|
|
assert(dummys==0)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- We do not test the actual callback logic here. The AceEvent tests do that plenty.
|
|
|
|
-----------------------------------------------------------------------
|
|
print "OK"
|
|
|