feat!: replace split with mapAtom

This commit is contained in:
Richard 2024-03-03 22:50:59 -08:00
parent fc3cd6d9ad
commit 4d4979daa9
11 changed files with 188 additions and 245 deletions

View file

@ -0,0 +1,105 @@
local atom = require(script.Parent.Parent.atom)
local mapAtom = require(script.Parent.Parent.mapAtom)
local observe = require(script.Parent.Parent.observe)
return function()
it("returns mapped atoms", function()
local itemsAtom = atom({ "a", "b", "c" })
local mappedAtom = mapAtom(itemsAtom, function(value, key)
return string.upper(value), key
end)
local updates = 0
mappedAtom.listeners[function()
updates += 1
end] = true
for key = 1, 3 do
local item = mappedAtom()[key]
expect(item).to.equal(string.upper(itemsAtom()[key]))
end
itemsAtom({ "d", "e", "f" })
expect(updates).to.equal(1)
for key = 1, 3 do
local item = mappedAtom()[key]
expect(item).to.equal(string.upper(itemsAtom()[key]))
end
itemsAtom({ [1] = "d", [3] = "f" })
expect(mappedAtom()[2]).to.never.be.ok()
expect(updates).to.equal(2)
end)
it("uses key extractor", function()
local itemsAtom = atom({ { key = 1 }, { key = 2 }, { key = 3 } })
local mappedAtom = mapAtom(itemsAtom, function(item)
return item, item.key
end)
for key = 1, 3 do
local item = mappedAtom()[key]
expect(item).to.equal(itemsAtom()[key])
end
local previous = mappedAtom()
itemsAtom({ itemsAtom()[1], itemsAtom()[3] })
expect(mappedAtom()[1]).to.equal(previous[1])
expect(mappedAtom()[1]).to.equal(itemsAtom()[1])
expect(mappedAtom()[2]).to.never.be.ok()
expect(mappedAtom()[3]).to.equal(previous[3])
expect(mappedAtom()[3]).to.equal(itemsAtom()[2])
end)
it("allows observe()", function()
local itemsAtom = atom({
{ key = 1, value = "a" },
{ key = 2, value = "b" },
{ key = 3, value = "c" },
})
local mappedAtom = mapAtom(itemsAtom, function(item)
return item, item.key
end)
local added = 0
local deleted = 0
local _, flush = observe(mappedAtom, function(item, key)
expect(item).to.equal(itemsAtom()[key])
added += 1
return function()
expect(mappedAtom()[key]).to.never.be.ok()
deleted += 1
end
end)
expect(added).to.equal(3)
expect(deleted).to.equal(0)
itemsAtom({ itemsAtom()[1], itemsAtom()[3] })
flush()
expect(added).to.equal(3)
expect(deleted).to.equal(1)
itemsAtom({})
flush()
expect(added).to.equal(3)
expect(deleted).to.equal(3)
end)
it("unmounts from parent atom", function()
local itemsAtom = atom({})
local mappedAtom = mapAtom(itemsAtom, function(item, key)
return item, key
end)
expect((next(itemsAtom.listeners))).to.be.ok()
mappedAtom:unmount()
expect((next(itemsAtom.listeners))).to.never.be.ok()
end)
end

View file

@ -1,136 +0,0 @@
local atom = require(script.Parent.Parent.atom)
local isAtom = require(script.Parent.Parent.isAtom)
local observe = require(script.Parent.Parent.observe)
local split = require(script.Parent.Parent.split)
return function()
it("returns split atoms", function()
local itemsAtom = atom({ "a", "b", "c" })
local itemAtoms = split(itemsAtom)
local updates = 0
itemAtoms.listeners[function()
updates += 1
end] = true
for key = 1, 3 do
local itemAtom = itemAtoms()[key]
assert(isAtom(itemAtom), `itemAtom {key} is not an atom; got {typeof(itemAtom)}`)
expect(itemAtom()).to.equal(itemsAtom()[key])
end
local prevAtoms = itemAtoms()
itemsAtom({ "d", "e", "f" })
expect(updates).to.equal(1)
for key = 1, 3 do
local itemAtom = itemAtoms()[key]
assert(itemAtom == prevAtoms[key] :: any, `itemAtom {key} is not the same atom; got {typeof(itemAtom)}`)
expect(itemAtom()).to.equal(itemsAtom()[key])
end
itemsAtom({ [1] = "d", [3] = "f" })
expect(itemAtoms()[2]).to.never.be.ok()
expect(updates).to.equal(2)
end)
it("has writable items", function()
local itemsAtom = atom({ "a", "b", "c" })
local itemAtoms = split(itemsAtom)
local updates = 0
itemAtoms.listeners[function()
updates += 1
end] = true
itemAtoms()[2]("x")
expect(updates).to.equal(1)
expect(itemsAtom()[2]).to.equal("x")
expect(itemAtoms()[2]()).to.equal("x")
end)
it("uses key extractor", function()
local itemsAtom = atom({ { key = 1 }, { key = 2 }, { key = 3 } })
local itemAtoms = split(itemsAtom, function(item)
return item.key
end)
for key = 1, 3 do
local itemAtom = itemAtoms()[key]
expect(itemAtom()).to.equal(itemsAtom()[key])
end
local prevAtoms = itemAtoms()
itemsAtom({ itemsAtom()[1], itemsAtom()[3] })
expect(itemAtoms()[1]).to.equal(prevAtoms[1])
expect(itemAtoms()[1]()).to.equal(itemsAtom()[1])
expect(itemAtoms()[2]).to.never.be.ok()
expect(itemAtoms()[3]).to.equal(prevAtoms[3])
expect(itemAtoms()[3]()).to.equal(itemsAtom()[2])
end)
it("allows observe()", function()
local itemsAtom = atom({
{ key = 1, value = "a" },
{ key = 2, value = "b" },
{ key = 3, value = "c" },
})
local itemAtoms = split(itemsAtom, function(item)
return item.key
end)
local added = 0
local updated = 0
local deleted = 0
local _, flush = observe(itemAtoms, function(item, key)
expect(item()).to.equal(itemsAtom()[key])
item.listeners[function(value)
expect(value).to.equal(itemsAtom()[key])
updated += 1
end] = true
added += 1
return function()
expect(itemAtoms()[key]).to.never.be.ok()
deleted += 1
end
end)
expect(added).to.equal(3)
expect(updated).to.equal(0)
expect(deleted).to.equal(0)
itemsAtom({ itemsAtom()[1], itemsAtom()[3] })
flush()
expect(added).to.equal(3)
expect(updated).to.equal(0)
expect(deleted).to.equal(1)
itemAtoms()[1]({ key = 1, value = "x" })
flush()
expect(added).to.equal(3)
expect(updated).to.equal(1)
expect(deleted).to.equal(1)
itemsAtom({})
flush()
expect(added).to.equal(3)
expect(updated).to.equal(1)
expect(deleted).to.equal(3)
end)
it("unmounts from parent atom", function()
local itemsAtom = atom({})
local itemAtoms = split(itemsAtom)
expect((next(itemsAtom.listeners))).to.be.ok()
itemAtoms:unmount()
expect((next(itemsAtom.listeners))).to.never.be.ok()
end)
end