Files
rojo/plugin/src/Reconciler/diff.spec.lua
2021-07-02 16:12:12 -04:00

289 lines
7.0 KiB
Lua

return function()
local Log = require(script.Parent.Parent.Parent.Log)
local InstanceMap = require(script.Parent.Parent.InstanceMap)
local PatchSet = require(script.Parent.Parent.PatchSet)
local diff = require(script.Parent.diff)
local function isEmpty(table)
return next(table) == nil, "Table was not empty"
end
local function size(dict)
local len = 0
for _ in pairs(dict) do
len = len + 1
end
return len
end
it("should generate an empty patch for empty instances", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Some Name",
Properties = {},
Children = {},
},
}
local rootInstance = Instance.new("Folder")
rootInstance.Name = "Some Name"
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
assert(isEmpty(patch.added))
assert(isEmpty(patch.updated))
end)
it("should generate a patch with a changed name", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Some Name",
Properties = {},
Children = {},
},
}
local rootInstance = Instance.new("Folder")
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
assert(isEmpty(patch.added))
expect(#patch.updated).to.equal(1)
local update = patch.updated[1]
expect(update.id).to.equal("ROOT")
expect(update.changedName).to.equal("Some Name")
assert(isEmpty(update.changedProperties))
end)
it("should generate a patch with a changed property", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "StringValue",
Name = "Value",
Properties = {
Value = {
String = "Hello, world!",
},
},
Children = {},
},
}
local rootInstance = Instance.new("StringValue")
rootInstance.Value = "Initial Value"
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
assert(isEmpty(patch.added))
expect(#patch.updated).to.equal(1)
local update = patch.updated[1]
expect(update.id).to.equal("ROOT")
expect(update.changedName).to.equal(nil)
expect(size(update.changedProperties)).to.equal(1)
local patchProperty = update.changedProperties["Value"]
expect(patchProperty).to.be.a("table")
local ty, value = next(patchProperty)
expect(ty).to.equal("String")
expect(value).to.equal("Hello, world!")
end)
it("should generate an empty patch if no properties changed", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "StringValue",
Name = "Value",
Properties = {
Value = {
String = "Hello, world!",
},
},
Children = {},
},
}
local rootInstance = Instance.new("StringValue")
rootInstance.Value = "Hello, world!"
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(PatchSet.isEmpty(patch), "expected empty patch")
end)
it("should ignore unknown properties", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {
FAKE_PROPERTY = {
String = "Hello, world!",
},
},
Children = {},
},
}
local rootInstance = Instance.new("Folder")
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
assert(isEmpty(patch.added))
assert(isEmpty(patch.updated))
end)
--[[
Because rbx_dom_lua resolves non-canonical properties to their canonical
variants, this test does not work as intended.
Instead, heat_xml is diffed with Heat, the canonical property variant,
and a patch trying to assign to heat_xml is generated. This is
incorrect, but will require more invasive changes to fix later.
]]
itFIXME("should ignore unreadable properties", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Fire",
Name = "Fire",
Properties = {
-- heat_xml is a serialization-only property that is not
-- exposed to Lua.
heat_xml = {
Float32 = 5,
},
},
Children = {},
},
}
local rootInstance = Instance.new("Fire")
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
Log.warn("{:#?}", patch)
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
assert(isEmpty(patch.added))
assert(isEmpty(patch.updated))
end)
it("should generate a patch removing unknown children by default", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {},
Children = {},
},
}
local rootInstance = Instance.new("Folder")
local unknownChild = Instance.new("Folder")
unknownChild.Parent = rootInstance
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.added))
assert(isEmpty(patch.updated))
expect(#patch.removed).to.equal(1)
expect(patch.removed[1]).to.equal(unknownChild)
end)
it("should generate an empty patch if unknown children should be ignored", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {},
Children = {},
Metadata = {
ignoreUnknownInstances = true,
},
},
}
local rootInstance = Instance.new("Folder")
local unknownChild = Instance.new("Folder")
unknownChild.Parent = rootInstance
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.added))
assert(isEmpty(patch.updated))
assert(isEmpty(patch.removed))
end)
it("should generate a patch with an added child", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {},
Children = {"CHILD"},
},
CHILD = {
ClassName = "Folder",
Name = "Child",
Properties = {},
Children = {},
},
}
local rootInstance = Instance.new("Folder")
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.updated))
assert(isEmpty(patch.removed))
expect(size(patch.added)).to.equal(1)
expect(patch.added["CHILD"]).to.equal(virtualInstances["CHILD"])
end)
end