Files
rojo/plugin/src/ChangeBatcher/init.spec.lua
Kenneth Loeffler 9d0b313261 Add ChangeBatcher to plugin for two-way sync (#478)
* Implement ChangeBatcher

* Use ChangeBatcher for two-way sync

* Pause updates during patch application

* I can English good

* Break after encountering a nil Parent change

This prevents __flush from erroring out when an instance's Parent is
changed to nil and it has other property changes in the same batch.

* Update rbx_dom_lua

* Don't connect changed listeners in a running game

 #468 made me realize how bad of an idea this is in general...

* Update TestEZ and fix sibling Ref reification test

* Add ChangeBatcher tests

* Test instance unpausing by breaking functionality out to __cycle

* Break up the module a bit and improve tests

* Shuffle requires around and edit comment

* Break out more stuff, rename createChangePatch -> createPatchSet

* Make ChangeBatcher responsible for unpausing all paused instances

This somewhat improves the situation (of course, it would preferrable
to not have to hack around this problem with Source at all). It also
sets us up nicely if we come across any other properties that do
anything similar.

* Remove old reference to pausedBatchInstances

* Use RenderStepped instead of Heartbeat and trash multi-frame pauses

I probably should have done this in the first place...

ChangeBatcher still needs to unpause instances, but we don't need to
hold pauses for any longer than one cycle.

* Remove useless branch

* if not next(x) -> if next(x) == nil

* Add InstanceMap:unpauseAllInstances, use it in ChangeBatcher

* Move IsRunning check to InstanceMap:__maybeFireInstanceChanged
2021-10-18 18:18:51 -04:00

102 lines
3.1 KiB
Lua

return function()
local ChangeBatcher = require(script.Parent)
local InstanceMap = require(script.Parent.Parent.InstanceMap)
local PatchSet = require(script.Parent.Parent.PatchSet)
local noop = function() end
describe("new", function()
it("should create a new ChangeBatcher", function()
local instanceMap = InstanceMap.new()
local changeBatcher = ChangeBatcher.new(instanceMap, noop)
expect(changeBatcher.__pendingPropertyChanges).to.be.a("table")
expect(next(changeBatcher.__pendingPropertyChanges)).to.equal(nil)
expect(changeBatcher.__onChangesFlushed).to.equal(noop)
expect(changeBatcher.__instanceMap).to.equal(instanceMap)
expect(typeof(changeBatcher.__renderSteppedConnection)).to.equal("RBXScriptConnection")
end)
end)
describe("stop", function()
it("should disconnect the RenderStepped connection", function()
local changeBatcher = ChangeBatcher.new(InstanceMap.new(), noop)
changeBatcher:stop()
expect(changeBatcher.__renderSteppedConnection.Connected).to.equal(false)
end)
end)
describe("add", function()
it("should add property changes to be considered for the current batch", function()
local instanceMap = InstanceMap.new()
local changeBatcher = ChangeBatcher.new(instanceMap, noop)
local part = Instance.new("Part")
instanceMap:insert("PART", part)
changeBatcher:add(part, "Name")
local properties = changeBatcher.__pendingPropertyChanges[part]
expect(properties).to.be.a("table")
expect(properties.Name).to.be.ok()
changeBatcher:add(part, "Position")
expect(properties.Position).to.be.ok()
end)
end)
describe("__cycle", function()
it("should immediately unpause any paused instances after each cycle", function()
local instanceMap = InstanceMap.new()
local changeBatcher = ChangeBatcher.new(instanceMap, noop)
local part = Instance.new("Part")
instanceMap.pausedUpdateInstances[part] = true
changeBatcher:__cycle(0)
expect(instanceMap.pausedUpdateInstances[part]).to.equal(nil)
end)
end)
describe("__flush", function()
it("should return nil when there are no changes to process", function()
local changeBatcher = ChangeBatcher.new(InstanceMap.new(), noop)
expect(changeBatcher:__flush()).to.equal(nil)
end)
it("should return a patch when there are changes to process and the resulting patch is non-empty", function()
local instanceMap = InstanceMap.new()
local changeBatcher = ChangeBatcher.new(instanceMap, noop)
local part = Instance.new("Part")
instanceMap:insert("PART", part)
changeBatcher.__pendingPropertyChanges[part] = {
Position = true,
Name = true,
}
local patch = changeBatcher:__flush()
assert(PatchSet.validate(patch))
end)
it("should return nil when there are changes to process and the resulting patch is empty", function()
local instanceMap = InstanceMap.new()
local changeBatcher = ChangeBatcher.new(instanceMap, noop)
local part = Instance.new("Part")
instanceMap:insert("PART", part)
changeBatcher.__pendingPropertyChanges[part] = {
NonExistentProperty = true,
}
expect(changeBatcher:__flush()).to.equal(nil)
end)
end)
end