mirror of
https://github.com/littensy/charm.git
synced 2026-10-21 19:54:09 +00:00
refactor!: run effects in batched
This commit is contained in:
parent
4a48dacfbd
commit
025d9b2208
4 changed files with 125 additions and 18 deletions
|
|
@ -239,8 +239,11 @@ test("should handle side effect with inner effects", function()
|
|||
table.clear(order)
|
||||
setB(1)
|
||||
setA(1)
|
||||
assert(table.concat(order) == "ba", `wrong order: {table.concat(order)}`)
|
||||
end)
|
||||
|
||||
-- DEVIATION: This assertion was moved outside of the effect so that it
|
||||
-- runs after the batch updates have been processed
|
||||
assert(table.concat(order) == "ba", `wrong order: {table.concat(order)}`)
|
||||
end)
|
||||
|
||||
test("should handle flags are indirectly updated during checkDirty", function()
|
||||
|
|
@ -268,7 +271,48 @@ test("should handle flags are indirectly updated during checkDirty", function()
|
|||
assert(triggers == 2, "did not update indirectly")
|
||||
end)
|
||||
|
||||
test("should allow recursion", function()
|
||||
test("should not execute skipped effects from previous failed flush when updating unrelated signal", function()
|
||||
local a, setA = signal(0)
|
||||
local b, setB = signal(0)
|
||||
local c, setC = signal(0)
|
||||
local d = computed(function()
|
||||
c()
|
||||
return 0
|
||||
end)
|
||||
|
||||
local effect3Executed = false
|
||||
|
||||
effect(function()
|
||||
a()
|
||||
end)
|
||||
effect(function()
|
||||
if a() == 2 then
|
||||
error("Error in effect 2")
|
||||
end
|
||||
end)
|
||||
effect(function()
|
||||
a()
|
||||
d()
|
||||
effect3Executed = true
|
||||
end)
|
||||
effect(function()
|
||||
b()
|
||||
end)
|
||||
|
||||
setA(1)
|
||||
|
||||
effect3Executed = false
|
||||
local success, err = pcall(setA, 2)
|
||||
assert(not success and string.find(tostring(err), "Error in effect 2"), `bad error: {err}`)
|
||||
|
||||
assert(not effect3Executed, "effect 3 should not have executed after failed flush")
|
||||
setB(1)
|
||||
assert(not effect3Executed, "effect 3 should not have executed after updating unrelated signal b")
|
||||
setC(1)
|
||||
assert(effect3Executed, "effect 3 should have executed after updating signal c")
|
||||
end)
|
||||
|
||||
test("should allow finite recursion", function()
|
||||
local src, setSrc = signal(0)
|
||||
local order = {}
|
||||
|
||||
|
|
@ -364,7 +408,7 @@ test("should run cleanups outside any evaluation context", function()
|
|||
assert(calls == 0, "should not run after b update")
|
||||
end)
|
||||
|
||||
test("infinite recursion should eventually throw", function()
|
||||
test.skip("infinite recursion should eventually throw", function()
|
||||
local counter, setCounter = signal(0)
|
||||
|
||||
local success = pcall(function()
|
||||
|
|
@ -451,4 +495,24 @@ test("should reset the cleanup if the effect throws", function()
|
|||
assert(calls == 1, "should not call cleanup again after resetting value")
|
||||
end)
|
||||
|
||||
test("recursive effects should run and cleanup in order", function()
|
||||
local a, setA = signal(0)
|
||||
local order = {}
|
||||
|
||||
effect(function()
|
||||
local value = a()
|
||||
table.insert(order, `+{value}`)
|
||||
if value < 3 then
|
||||
setA(value + 1)
|
||||
end
|
||||
return function()
|
||||
table.insert(order, `-{value}`)
|
||||
end
|
||||
end)
|
||||
assert(table.concat(order) == "+0-0+1-1+2-2+3", `bad order: {table.concat(order)}`)
|
||||
table.clear(order)
|
||||
setA(100)
|
||||
assert(table.concat(order) == "-3+100", `bad order: {table.concat(order)}`)
|
||||
end)
|
||||
|
||||
return {}
|
||||
|
|
|
|||
|
|
@ -70,10 +70,32 @@ test("should run indirect effect cleanup", function()
|
|||
assert(cleanups == 2, "should not cleanup after update")
|
||||
end)
|
||||
|
||||
test("should dispose inner effects if created in an effect", function()
|
||||
local source, setSource = signal(1)
|
||||
local triggers = 0
|
||||
local dispose
|
||||
|
||||
effect(function()
|
||||
dispose = effectScope(function()
|
||||
effect(function()
|
||||
source()
|
||||
triggers += 1
|
||||
end)
|
||||
end)
|
||||
assert(triggers == 1, "did not run initially")
|
||||
end)
|
||||
|
||||
setSource(2)
|
||||
assert(triggers == 2, "did not run after update")
|
||||
dispose()
|
||||
setSource(3)
|
||||
assert(triggers == 2, "ran after dispose")
|
||||
end)
|
||||
|
||||
test("should disallow yielding", function()
|
||||
local success = pcall(function()
|
||||
effectScope(function()
|
||||
(if task then task.wait else coroutine.yield :: never)()
|
||||
coroutine.yield()
|
||||
end)
|
||||
end)
|
||||
assert(not success, "should error on yield")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue