Files
ShaguTweaks-ClassicAPI/tests/test_cooldown_native.lua
T

142 lines
7.9 KiB
Lua

local root=(arg[1] or '.')..'/'
assert(loadfile(root..'mods/cooldown-numbers.lua'))
local function read(path)local f=assert(io.open(root..path));local s=f:read('*a');f:close();return s end
local helpers=read('helpers.lua')
local a=assert(string.find(helpers,'ShaguTweaks.TimeConvert = function',1,true))
local b=assert(string.find(helpers,'\nend',a,true))
local reference={ShaguTweaks={},ceil=math.ceil}
setmetatable(reference,{__index=getfenv(0)})
local chunk=assert(loadstring(string.sub(helpers,a,b+3)));setfenv(chunk,reference);chunk()
local env=setmetatable({},{__index=getfenv(0)});env._G=env
local frames,formatted,cvar,now={},0,'1',101
local nativeFactory
local function newFrame(parent)
local f={parent=parent,scripts={},visible=true,alpha=1}
function f:GetParent()return self.parent end
function f:GetHeight()return self.height or 36 end
function f:GetFrameLevel()return 4 end
function f:GetAlpha()return self.alpha end
function f:SetAlpha(n)self.alpha=n end
function f:SetAllPoints()end
function f:SetFrameLevel()end
function f:SetScript(k,v)self.scripts[k]=v end
function f:RegisterEvent(k)self.event=k end
function f:Hide()self.visible=false end
function f:Show()self.visible=true end
function f:CreateFontString()
local text={}
function text:SetFont(font,size,flags)self.font,self.size,self.flags=font,size,flags end
function text:ClearAllPoints()end
function text:SetPoint()end
function text:SetTextColor()end
function text:SetText(value)self.value=value end
return text
end
return f
end
env.CreateFrame=function(kind,_,parent)
if kind=='Cooldown' and env.createNative then return env.createNative(parent) end
local f=newFrame(parent);table.insert(frames,f);return f
end
env.GetTime=function()return now end
env.GetCVar=function()return cvar end
env.SetCVar=function()error('must not change global cooldown policy')end
env.STANDARD_TEXT_FONT='font'
env.Enum={NumericRuleFormatRounding={Up=1}}
env.C_StringUtil={CreateNumericRuleFormatter=function()
formatted=formatted+1
local formatter={}
function formatter:SetBreakpoints(rules)self.rules=rules end
function formatter:FormatNumber(n)
local rule
for _,candidate in ipairs(self.rules)do if n>=candidate.threshold then rule=candidate end end
local function round(value,step)if step then return math.ceil(value/step)*step end;return value end
local value=round(n,rule.step)
if rule.components then value=round(value/rule.components[1].div,rule.components[1].step)end
return string.format(rule.format,value)
end
return formatter
end}
nativeFactory=env.C_StringUtil.CreateNumericRuleFormatter
local set
env.hooksecurefunc=function(name,callback)assert(name=='CooldownFrame_SetTimer');set=callback end
env.ShaguTweaks={T={},API={nativecooldowns=false},GetGlobalEnv=function()return env end,GetExpansion=function()return 'vanilla' end,
TimeConvert=reference.ShaguTweaks.TimeConvert,register=function(_,module)env.module=module;return module end}
local load=assert(loadfile(root..'mods/cooldown-numbers.lua'));setfenv(load,env);load();env.module:enable()
local parent=newFrame();parent.height=18
local function native(owner)
local f=newFrame(owner or parent);f.nativeText=f:CreateFontString()
function f:GetCountdownFontString()return self.nativeText end
function f:SetCountdownFormatter(value)self.formatter=value end
function f:SetMinimumCountdownDuration(value)self.minimum=value end
function f:SetHideCountdownNumbers(value)self.hidden=value end
function f:SetDrawSwipe(value)self.swipe=value end
function f:SetDrawEdge(value)self.edge=value end
function f:SetDrawBling(value)self.bling=value end
function f:SetCooldown(start,duration)self.start,self.duration=start,duration;self.visible=true;self.starts=(self.starts or 0)+1 end
return f
end
local cd=native();set(cd,100,20,1)
assert(not cd.cooldowntext and not cd.scripts.OnUpdate and not cd.hidden)
assert(cd.minimum==1999 and cd.nativeText.size==18*.64)
assert(table.getn(frames)==1 and frames[1].event=='CVAR_UPDATE')
local second=native();set(second,100,20,1)
assert(formatted==1 and second.formatter==cd.formatter,'one shared native formatter')
for _,n in ipairs({.01,.99,1,4.01,4.99,5,5.01,9.99,10,59,59.99,60,60.01,3599.99,3600,86399.99,86400,172801})do
assert(cd.formatter:FormatNumber(n)==reference.ShaguTweaks.TimeConvert(n),'TimeConvert mismatch at '..n)
end
set(cd,100,1.5,1);assert(cd.hidden and not cd.cooldowntext)
set(cd,100,2,1);assert(not cd.hidden)
set(cd,0,20,1);assert(cd.hidden)
set(cd,100,20,0);assert(cd.hidden)
set(cd,100,20,1);cd.noCooldownCount=true;set(cd,100,20,1);assert(cd.hidden)
cd.noCooldownCount=nil;cd.pfCooldownType='spell';set(cd,100,20,1);assert(cd.hidden)
cd.pfCooldownType=nil;cd.readable=true;set(cd,100,20,1);assert(cd.hidden)
cd.readable=nil
local foreign=native();foreign.pfCooldownType='spell';set(foreign,100,20,1)
assert(foreign.hidden==nil and foreign.formatter==nil,'must leave foreign-owned native setup alone')
local excluded=native();excluded.noCooldownCount=true;set(excluded,100,20,1)
assert(excluded.hidden and not excluded.cooldowntext and not excluded.formatter)
-- CVar changes switch existing native indicators without setting the CVar.
local watcher=frames[1]
cvar='0';watcher.scripts.OnEvent()
assert(cd.cooldowntext and cd.cooldowntext.visible and cd.hidden)
local function tick(frame,dt)env.this,env.arg1=frame,dt;frame.scripts.OnUpdate();env.this,env.arg1=nil,nil end
tick(cd.cooldowntext,.1);assert(cd.cooldowntext.text.value==reference.ShaguTweaks.TimeConvert(19))
local frameCount=table.getn(frames);watcher.scripts.OnEvent();assert(table.getn(frames)==frameCount)
cvar='1';watcher.scripts.OnEvent();assert(not cd.cooldowntext.visible and not cd.hidden)
-- Legacy Models keep the old renderer, including alpha, expiry and clock wrap.
local model=newFrame(parent);set(model,100,20,1);assert(model.cooldowntext.visible)
model.alpha=.4;tick(model.cooldowntext,.1);assert(model.cooldowntext.alpha==.4)
now=121;tick(model.cooldowntext,.1);assert(not model.cooldowntext.visible)
local cycle=2^32/1000;now=1;set(model,cycle-2,10,1);tick(model.cooldowntext,.1)
assert(model.cooldowntext.text.value==reference.ShaguTweaks.TimeConvert(7))
-- Native numeric children optimize legacy Models without changing their sweep.
env.ShaguTweaks.API.nativecooldowns=true;env.createNative=native
local legacy=newFrame(parent);set(legacy,1,20,1)
local numbers=legacy.stCountdownNativeFrame
assert(numbers and not legacy.cooldowntext and not numbers.scripts.OnUpdate)
assert(numbers.parent==legacy and numbers.start==1 and numbers.duration==20)
assert(numbers.swipe==false and numbers.edge==false and numbers.bling==false)
local starts=numbers.starts;set(numbers,1,20,1)
assert(numbers.starts==starts,'native helper must not recursively decorate itself')
set(legacy,1,1,1);assert(not numbers.visible)
set(legacy,1,20,1);assert(numbers.visible)
cvar='0';watcher.scripts.OnEvent();assert(not numbers.visible and legacy.cooldowntext.visible)
cvar='1';watcher.scripts.OnEvent();assert(numbers.visible and not legacy.cooldowntext.visible)
assert(legacy.stCountdownNativeFrame==numbers)
legacy.noCooldownCount=true;set(legacy,1,20,1);assert(not numbers.visible)
-- A rejected native frame creation safely falls back and is not retried.
local attempts=0;env.createNative=function()attempts=attempts+1;error('unsupported frame')end
local unsupported=newFrame(parent);set(unsupported,1,20,1);set(unsupported,1,20,1)
assert(unsupported.cooldowntext.visible and attempts==1)
env.ShaguTweaks.API.nativecooldowns=false
-- Missing formatter APIs retain one renderer, suppressing native duplicates.
env.C_StringUtil.CreateNumericRuleFormatter=nil
local older=native();set(older,1,20,1)
assert(older.hidden and older.cooldowntext.visible)
env.C_StringUtil.CreateNumericRuleFormatter=nativeFactory
set(model,1,1,1);assert(not model.cooldowntext.visible)
model.noCooldownCount=true;set(model,1,20,1);assert(not model.cooldowntext.visible)
print('Cooldown numbers: shared native formatter, TimeConvert boundaries, global-CVar ownership/live changes, foreign flags, GCDs, legacy/older API fallback, alpha/expiry and clock wrap passed')