mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
fix: check if cleanup functions disposed effect
This commit is contained in:
parent
1f4c7c7a65
commit
4a48dacfbd
3 changed files with 85 additions and 1 deletions
|
|
@ -202,6 +202,10 @@ local function run(effect: EffectNode)
|
||||||
if bit32.btest(flags, DIRTY) or (bit32.btest(flags, PENDING) and checkDirty(effect.deps :: Link, effect)) then
|
if bit32.btest(flags, DIRTY) or (bit32.btest(flags, PENDING) and checkDirty(effect.deps :: Link, effect)) then
|
||||||
runCleanups(effect.cleanups)
|
runCleanups(effect.cleanups)
|
||||||
|
|
||||||
|
if effect.flags == NONE then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
cycle += 1
|
cycle += 1
|
||||||
effect.depsTail = nil
|
effect.depsTail = nil
|
||||||
effect.flags = WATCHING
|
effect.flags = WATCHING
|
||||||
|
|
@ -217,6 +221,10 @@ local function run(effect: EffectNode)
|
||||||
elseif result then
|
elseif result then
|
||||||
table.insert(effect.cleanups, noYield(result))
|
table.insert(effect.cleanups, noYield(result))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if effect.flags == NONE then
|
||||||
|
runCleanups(effect.cleanups)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
effect.flags = WATCHING
|
effect.flags = WATCHING
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -375,4 +375,80 @@ test("infinite recursion should eventually throw", function()
|
||||||
assert(not success, "should have thrown")
|
assert(not success, "should have thrown")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
test("should not retrigger the effect if the cleanup modifies one of the dependencies", function()
|
||||||
|
local a, setA = signal(0)
|
||||||
|
local calls = {}
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
table.insert(calls, a())
|
||||||
|
return function()
|
||||||
|
setA(2)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
assert(#calls == 1, "should have run once initially")
|
||||||
|
table.clear(calls)
|
||||||
|
|
||||||
|
setA(1)
|
||||||
|
assert(#calls == 1, "should run once after an update")
|
||||||
|
assert(calls[1] == 2, `bad call: {calls[1]}`)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("should run the cleanup if the effect disposes itself", function()
|
||||||
|
local a, setA = signal(0)
|
||||||
|
local calls = 0
|
||||||
|
local dispose
|
||||||
|
|
||||||
|
dispose = effect(function()
|
||||||
|
if a() > 0 then
|
||||||
|
dispose()
|
||||||
|
return function()
|
||||||
|
calls += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
assert(calls == 0, "should not have called cleanup initially")
|
||||||
|
setA(1)
|
||||||
|
assert(calls == 1, "should have called cleanup once after first update")
|
||||||
|
setA(2)
|
||||||
|
assert(calls == 1, "should not call cleanup again after second update")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("should not run the effect if the cleanup function disposes it", function()
|
||||||
|
local a, setA = signal(0)
|
||||||
|
local calls = 0
|
||||||
|
local dispose
|
||||||
|
|
||||||
|
dispose = effect(function()
|
||||||
|
a()
|
||||||
|
calls += 1
|
||||||
|
return function()
|
||||||
|
dispose()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
assert(calls == 1, "should have run effect once initially")
|
||||||
|
setA(1)
|
||||||
|
assert(calls == 1, "should not run effect again after update")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("should reset the cleanup if the effect throws", function()
|
||||||
|
local a, setA = signal(0)
|
||||||
|
local calls = 0
|
||||||
|
|
||||||
|
effect(function()
|
||||||
|
if a() == 0 then
|
||||||
|
return function()
|
||||||
|
calls += 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("hello")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
assert(calls == 0, "should not have called cleanup initially")
|
||||||
|
local success, err = pcall(setA, 1)
|
||||||
|
assert(not success and string.find(tostring(err), "hello"), `bad error: {err}`)
|
||||||
|
assert(calls == 1, "should have called cleanup once after throwing")
|
||||||
|
setA(0)
|
||||||
|
assert(calls == 1, "should not call cleanup again after resetting value")
|
||||||
|
end)
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ wally = "UpliftGames/wally@0.3.2"
|
||||||
rojo = "rojo-rbx/rojo@7.6.1"
|
rojo = "rojo-rbx/rojo@7.6.1"
|
||||||
stylua = "johnnymorganz/stylua@2.3.1"
|
stylua = "johnnymorganz/stylua@2.3.1"
|
||||||
selene = "Kampfkarren/selene@0.30.0"
|
selene = "Kampfkarren/selene@0.30.0"
|
||||||
luau-lsp = "johnnymorganz/luau-lsp@1.62.0"
|
luau-lsp = "johnnymorganz/luau-lsp@1.63.0"
|
||||||
lute = "luau-lang/lute@0.1.0-nightly.20260219"
|
lute = "luau-lang/lute@0.1.0-nightly.20260219"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue