mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
This commit is contained in:
parent
f7ce5f024d
commit
7cdcebf03c
11 changed files with 367 additions and 233 deletions
219
test/tests.luau
219
test/tests.luau
|
|
@ -363,6 +363,7 @@ end)
|
|||
TEST("watch()", function()
|
||||
local source = vide.source
|
||||
local watch = vide.watch
|
||||
local cleanup = vide.cleanup
|
||||
|
||||
do CASE "Capture states"
|
||||
local a = source(1)
|
||||
|
|
@ -405,7 +406,7 @@ TEST("watch()", function()
|
|||
local unwatch = watch(function()
|
||||
state()
|
||||
effect_runcount += 1
|
||||
return function() cleanup_runcount += 1 end
|
||||
cleanup(function() cleanup_runcount += 1 end)
|
||||
end)
|
||||
|
||||
CHECK(effect_runcount == 1)
|
||||
|
|
@ -413,7 +414,12 @@ TEST("watch()", function()
|
|||
state(2)
|
||||
CHECK(effect_runcount == 2)
|
||||
CHECK(cleanup_runcount == 1)
|
||||
|
||||
unwatch()
|
||||
unwatch = nil :: any
|
||||
gc()
|
||||
vide.step(0)
|
||||
|
||||
CHECK(effect_runcount == 2)
|
||||
CHECK(cleanup_runcount == 2)
|
||||
end
|
||||
|
|
@ -478,6 +484,117 @@ TEST("watch()", function()
|
|||
end
|
||||
end)
|
||||
|
||||
TEST("cleanup()", function()
|
||||
local source = vide.source
|
||||
local derive = vide.derive
|
||||
local watch = vide.watch
|
||||
local cleanup = vide.cleanup
|
||||
|
||||
do CASE "Cleanup runs for watcher"
|
||||
local state = source(1)
|
||||
|
||||
local watched = 0
|
||||
local cleaned = 0
|
||||
|
||||
local stop = watch(function()
|
||||
state()
|
||||
watched += 1
|
||||
cleanup(function()
|
||||
cleaned += 1
|
||||
end)
|
||||
end)
|
||||
|
||||
CHECK(watched == 1)
|
||||
CHECK(cleaned == 0)
|
||||
|
||||
state(2)
|
||||
|
||||
CHECK(watched == 2)
|
||||
CHECK(cleaned == 1)
|
||||
|
||||
stop()
|
||||
|
||||
do -- vide detects by iterating through and checking for gc'd refs
|
||||
stop = nil :: any
|
||||
gc()
|
||||
vide.step(0)
|
||||
end
|
||||
|
||||
CHECK(watched == 2)
|
||||
CHECK(cleaned == 2)
|
||||
end
|
||||
|
||||
do CASE "Scoped"
|
||||
local function setup()
|
||||
local state = source(1)
|
||||
local obj = { cleaned = 0 }
|
||||
|
||||
local _stop = watch(function()
|
||||
state()
|
||||
cleanup(function()
|
||||
obj.cleaned += 1
|
||||
end)
|
||||
end)
|
||||
|
||||
return state, obj
|
||||
end
|
||||
|
||||
local stateA, objA = setup()
|
||||
local stateB, objB = setup()
|
||||
|
||||
CHECK(objA.cleaned == 0)
|
||||
CHECK(objB.cleaned == 0)
|
||||
|
||||
stateA(2)
|
||||
|
||||
CHECK(objA.cleaned == 1)
|
||||
CHECK(objB.cleaned == 0)
|
||||
|
||||
stateB(2)
|
||||
|
||||
CHECK(objA.cleaned == 1)
|
||||
CHECK(objB.cleaned == 1)
|
||||
|
||||
do
|
||||
stateA = nil :: any
|
||||
stateB = nil :: any
|
||||
gc()
|
||||
vide.step(0)
|
||||
end
|
||||
|
||||
CHECK(objA.cleaned == 2)
|
||||
CHECK(objB.cleaned == 2)
|
||||
end
|
||||
|
||||
do CASE "Multiple cleanup"
|
||||
local state = source(1)
|
||||
|
||||
local queue = {}
|
||||
|
||||
watch(function()
|
||||
state()
|
||||
cleanup(function() table.insert(queue, 1) end)
|
||||
cleanup(function() table.insert(queue, 2) end)
|
||||
end)
|
||||
|
||||
CHECK(testkit.seq(queue, {}))
|
||||
state(2)
|
||||
CHECK(testkit.seq(queue, { 1, 2 }))
|
||||
state(3)
|
||||
CHECK(testkit.seq(queue, { 1, 2, 1, 2 }))
|
||||
|
||||
do
|
||||
state = nil :: any
|
||||
gc()
|
||||
vide.step(0)
|
||||
end
|
||||
|
||||
-- todo: guarantee call order when gc? (currently not)
|
||||
--testkit.print2(queue)
|
||||
--CHECK(testkit.seq(queue, { 1, 2, 1, 2, 1, 2 }))
|
||||
end
|
||||
end)
|
||||
|
||||
TEST("create()", function()
|
||||
local create = vide.create
|
||||
local source = vide.source
|
||||
|
|
@ -894,6 +1011,7 @@ TEST("map()", function()
|
|||
end)
|
||||
|
||||
TEST("spring()", function()
|
||||
local create = vide.create
|
||||
local source = vide.source
|
||||
local spring = vide.spring
|
||||
|
||||
|
|
@ -909,43 +1027,43 @@ TEST("spring()", function()
|
|||
end
|
||||
|
||||
do CASE "Garbage collection"
|
||||
do -- `spring` should not allow gc of `state`
|
||||
local state = source(10)
|
||||
local _springed = spring(state, 1, 1)
|
||||
do -- `output` should not allow gc of `input`
|
||||
local input = source(10)
|
||||
local output = spring(input)
|
||||
|
||||
wref.state, state = state, nil :: any
|
||||
local wref = { input }
|
||||
input = nil :: any
|
||||
|
||||
gc()
|
||||
CHECK(wref.state)
|
||||
|
||||
CHECK(wref[1])
|
||||
end
|
||||
|
||||
do -- `value` should allow gc of `spring`
|
||||
local value = source(10)
|
||||
local springed = spring(value, 1, 1) :: State?
|
||||
do -- `input` should allow gc of `output`
|
||||
local input = source(10)
|
||||
local output = spring(input)
|
||||
|
||||
wref.springed, springed = springed, nil
|
||||
local wref = { output }
|
||||
output = nil :: any
|
||||
|
||||
gc()
|
||||
CHECK(not wref.springed)
|
||||
|
||||
CHECK(not wref[1])
|
||||
end
|
||||
end
|
||||
|
||||
local create = vide.create
|
||||
|
||||
do CASE "Garbage collection (binded)"
|
||||
local number = source(10)
|
||||
local springed = spring(number, 1, 1) :: State?
|
||||
local input = source(10)
|
||||
local output = spring(input, 1, 1)
|
||||
|
||||
local _label = create "TextLabel" {
|
||||
Text = springed
|
||||
Text = output
|
||||
}
|
||||
|
||||
wref.springed, springed = springed, nil
|
||||
local wref = { output }
|
||||
output = nil :: any
|
||||
|
||||
gc()
|
||||
CHECK(wref.springed) -- `springed` should not gc
|
||||
CHECK(wref[1]) -- `output` should not gc
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
@ -954,9 +1072,11 @@ TEST("Events", function()
|
|||
|
||||
local function Thing(props)
|
||||
local instance = Instance.new("Thing") :: any
|
||||
instance.Signal = (Signal.new() :: any) :: RBXScriptSignal & { Fire: any }
|
||||
testkit.print2(getmetatable(instance))
|
||||
return create(instance)(props)
|
||||
instance.Signal = Signal.new()
|
||||
|
||||
local clone = create(instance)(props)
|
||||
|
||||
return clone
|
||||
end
|
||||
|
||||
do CASE "Connect event"
|
||||
|
|
@ -969,7 +1089,7 @@ TEST("Events", function()
|
|||
end
|
||||
}
|
||||
|
||||
testkit.print2(getmetatable(val))
|
||||
-- testkit.print2(getmetatable(val))
|
||||
|
||||
CHECK(not connected)
|
||||
val.Value = 1; val.Signal:Fire(val.Value)
|
||||
|
|
@ -977,6 +1097,7 @@ TEST("Events", function()
|
|||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
TEST("Changed", function()
|
||||
local create = vide.create
|
||||
local Changed = vide.Changed
|
||||
|
|
@ -1023,6 +1144,7 @@ TEST("Changed", function()
|
|||
CHECK(Changed.Test == Changed.Test)
|
||||
end
|
||||
end)
|
||||
]]
|
||||
|
||||
--[[
|
||||
TEST("Created", function()
|
||||
|
|
@ -1050,7 +1172,6 @@ TEST("strict", function()
|
|||
vide.strict = true
|
||||
|
||||
local source = vide.source
|
||||
local unsource = vide.unsource
|
||||
local derive = vide.derive
|
||||
local watch = vide.watch
|
||||
|
||||
|
|
@ -1058,9 +1179,9 @@ TEST("strict", function()
|
|||
local state = source(1)
|
||||
|
||||
local ok = pcall(function()
|
||||
local _derived = derive(function(from)
|
||||
local _derived = derive(function()
|
||||
coroutine.yield()
|
||||
return from(state)
|
||||
return state()
|
||||
end)
|
||||
end)
|
||||
|
||||
|
|
@ -1071,9 +1192,9 @@ TEST("strict", function()
|
|||
local state = source(1)
|
||||
|
||||
local ok = pcall(function()
|
||||
local _derived = watch(function(from)
|
||||
local _derived = watch(function()
|
||||
coroutine.yield()
|
||||
local _ = from(state)
|
||||
state()
|
||||
end)
|
||||
end)
|
||||
|
||||
|
|
@ -1081,59 +1202,33 @@ TEST("strict", function()
|
|||
end
|
||||
|
||||
do CASE "Run derived callback twice"
|
||||
local state, set = source(1)
|
||||
local state = source(1)
|
||||
local runcount = 0
|
||||
|
||||
local derived = derive(function(from)
|
||||
local _ = derive(function()
|
||||
runcount += 1
|
||||
return from(state)
|
||||
return state()
|
||||
end)
|
||||
|
||||
CHECK(runcount == 2)
|
||||
set(2)
|
||||
local _ = derived()
|
||||
state(2)
|
||||
CHECK(runcount == 4)
|
||||
end
|
||||
|
||||
do CASE "Run watcher callback twice"
|
||||
local state, set = source(1)
|
||||
local state = source(1)
|
||||
local runcount = 0
|
||||
|
||||
watch(function(from)
|
||||
watch(function()
|
||||
runcount += 1
|
||||
local _ = from(state)
|
||||
state()
|
||||
end)
|
||||
|
||||
CHECK(runcount == 2)
|
||||
set(2)
|
||||
vide.step(1/60)
|
||||
state(2)
|
||||
CHECK(runcount == 4)
|
||||
end
|
||||
|
||||
do CASE "Does not allow non-layout properties"
|
||||
local ok = pcall(function()
|
||||
vide.create "Frame" {
|
||||
[vide.Layout] = {
|
||||
AnchorPoint = Vector2.new(0, 0.5),
|
||||
BackgroundColor3 = Color3.new(0, 0, 0)
|
||||
}
|
||||
}
|
||||
end)
|
||||
CHECK(not ok)
|
||||
end
|
||||
|
||||
do CASE "Does not allow same table set"
|
||||
local _, set = source()
|
||||
|
||||
local t = {}
|
||||
|
||||
set(t)
|
||||
|
||||
local ok = pcall(set, t)
|
||||
|
||||
CHECK(not ok)
|
||||
end
|
||||
|
||||
-- todo: add case for strict mode bindings
|
||||
end)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue