mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
136 lines
3.1 KiB
Text
136 lines
3.1 KiB
Text
local Charm = require("../Charm")
|
|
local client = require("../src/client")
|
|
local test = require("../../../tests/test")
|
|
|
|
test.afterEach(function()
|
|
client.removeAllSignals()
|
|
end)
|
|
|
|
test("should hydrate atom", function()
|
|
local a = Charm.atom(1)
|
|
|
|
client.addSignals({ a = a })
|
|
client.patch({
|
|
{ type = "init", data = { a = 2 } },
|
|
})
|
|
|
|
assert(a() == 2, "should set a to the initial value")
|
|
end)
|
|
|
|
test("should merge patch", function()
|
|
local a = Charm.atom({ b = 1, c = 2 })
|
|
local previous = a()
|
|
|
|
client.addSignals({ a = a })
|
|
client.patch({
|
|
{ type = "init", data = { a = a() } },
|
|
})
|
|
|
|
assert(a() == previous, "should set a to the initial value")
|
|
|
|
client.patch({
|
|
{ type = "patch", data = { a = { b = 3 } } },
|
|
})
|
|
|
|
assert(a() ~= previous, "should apply patch")
|
|
assert(a().b == 3, "should set b to the new value")
|
|
assert(a().c == 2, "should not change c")
|
|
end)
|
|
|
|
test("should merge patch (reactive)", function()
|
|
local a = Charm.reactive({ b = 1, c = 2 })
|
|
local runs = 0
|
|
|
|
Charm.effect(function()
|
|
local _ = a.b + a.c
|
|
runs += 1
|
|
end)
|
|
|
|
client.addSignals({ a = a })
|
|
client.patch({
|
|
{ type = "init", data = { a = { b = a.b, c = a.c } } },
|
|
})
|
|
|
|
assert(runs == 1, "should not trigger effect for redundant init")
|
|
|
|
client.patch({
|
|
{ type = "patch", data = { a = { b = 3 } } },
|
|
})
|
|
|
|
assert(a.b == 3, "should set b to the new value")
|
|
assert(a.c == 2, "should not change c")
|
|
assert(runs == 2, "should trigger effect for patch")
|
|
end)
|
|
|
|
test("should fix sparse array patches", function()
|
|
local a = Charm.atom({ 1 })
|
|
|
|
client.addSignals({ a = a })
|
|
client.patch({
|
|
{ type = "init", data = { a = a() } },
|
|
})
|
|
|
|
-- This patch would be the result of a diff between { 1 } and { 1, 2 } that
|
|
-- was JSON-serialized and deserialized. The client should be able to catch
|
|
-- this and convert the string key back to a number.
|
|
client.patch({
|
|
{ type = "patch", data = { a = { ["2"] = 2 } } },
|
|
})
|
|
|
|
assert(a()["2" :: any] == nil, "should convert serialized arrays to use numbers")
|
|
assert(a()[2] == 2, "should convert serialized arrays to use numbers")
|
|
end)
|
|
|
|
test("should merge multiple patches", function()
|
|
local a = Charm.atom(1)
|
|
local calls = {}
|
|
|
|
client.addSignals({ a = a })
|
|
|
|
Charm.subscribe(a, function(value)
|
|
table.insert(calls, value)
|
|
end)
|
|
|
|
client.patch({
|
|
{ type = "init", data = { a = a() } },
|
|
})
|
|
|
|
client.patch({
|
|
{ type = "patch", data = { a = 2 } },
|
|
{ type = "patch", data = { a = 3 } },
|
|
})
|
|
|
|
assert(a() == 3, "should apply the last patch")
|
|
assert(table.concat(calls) == "23", `wrong order: {table.concat(calls)}`)
|
|
end)
|
|
|
|
test("should batch patches", function()
|
|
local a = Charm.atom(0)
|
|
local b = Charm.atom(0)
|
|
local states = {}
|
|
|
|
client.addSignals({ a = a, b = b })
|
|
|
|
Charm.subscribe(a, function()
|
|
states.b = b()
|
|
end)
|
|
|
|
Charm.subscribe(b, function()
|
|
states.a = a()
|
|
end)
|
|
|
|
client.patch({
|
|
{ type = "init", data = { a = a(), b = b() } },
|
|
})
|
|
|
|
client.patch({
|
|
{ type = "patch", data = { a = 1, b = 2 } },
|
|
})
|
|
|
|
assert(a() == 1, "should set a to the new value")
|
|
assert(b() == 2, "should set b to the new value")
|
|
assert(states.a == 1, "sub to a should run after b updates")
|
|
assert(states.b == 2, "sub to b should run after a updates")
|
|
end)
|
|
|
|
return {}
|