return function()local D=require(script.Parent.createSignal)local F=require(script.Parent.createSpy)it("\115\104\111\117\108\100 \102\105\114\101 \115\117\098\115\099\114\105\098\101\114\115 \097\110\100 \100\105\115\099\111\110\110\101\099\116 \116\104\101\109",function()local t=D()local v=F()local G=t:subscribe(v.value);(expect(v.callCount)).to.equal(0)local u=1 local K={}local H="\104\101\108\108\111"t:fire(u,K,H);(expect(v.callCount)).to.equal(1)v:assertCalledWith(u,K,H)G()t:fire();(expect(v.callCount)).to.equal(1)end)it("\115\104\111\117\108\100 \104\097\110\100\108\101 \109\117\108\116\105\112\108\101 \115\117\098\115\099\114\105\098\101\114\115",function()local t=D()local v=F()local G=F()local u=t:subscribe(v.value)local K=t:subscribe(G.value);(expect(v.callCount)).to.equal(0);(expect(G.callCount)).to.equal(0)local H={}local r=67 t:fire(H,r);(expect(v.callCount)).to.equal(1)v:assertCalledWith(H,r);(expect(G.callCount)).to.equal(1)G:assertCalledWith(H,r)u()t:fire(r,H);(expect(v.callCount)).to.equal(1);(expect(G.callCount)).to.equal(2)G:assertCalledWith(r,H)K()end)it("\115\104\111\117\108\100 \115\116\111\112 \102\105\114\105\110\103 \097 \099\111\110\110\101\099\116\105\111\110 \105\102 \100\105\115\099\111\110\110\101\099\116\101\100 \109\105\100-\102\105\114\101",function()local t=D()local v local G local u=F(function()G()end)local K=F(function()v()end)v=t:subscribe(u.value)G=t:subscribe(K.value)t:fire();(expect(u.callCount+K.callCount)).to.equal(1)end)end
return function()
	local createSignal = require(script.Parent.createSignal)

	local createSpy = require(script.Parent.createSpy)

	it("should fire subscribers and disconnect them", function()
		local signal = createSignal()

		local spy = createSpy()
		local disconnect = signal:subscribe(spy.value)

		expect(spy.callCount).to.equal(0)

		local a = 1
		local b = {}
		local c = "hello"
		signal:fire(a, b, c)

		expect(spy.callCount).to.equal(1)
		spy:assertCalledWith(a, b, c)

		disconnect()

		signal:fire()

		expect(spy.callCount).to.equal(1)
	end)

	it("should handle multiple subscribers", function()
		local signal = createSignal()

		local spyA = createSpy()
		local spyB = createSpy()

		local disconnectA = signal:subscribe(spyA.value)
		local disconnectB = signal:subscribe(spyB.value)

		expect(spyA.callCount).to.equal(0)
		expect(spyB.callCount).to.equal(0)

		local a = {}
		local b = 67
		signal:fire(a, b)

		expect(spyA.callCount).to.equal(1)
		spyA:assertCalledWith(a, b)

		expect(spyB.callCount).to.equal(1)
		spyB:assertCalledWith(a, b)

		disconnectA()

		signal:fire(b, a)

		expect(spyA.callCount).to.equal(1)

		expect(spyB.callCount).to.equal(2)
		spyB:assertCalledWith(b, a)

		disconnectB()
	end)

	it("should stop firing a connection if disconnected mid-fire", function()
		local signal = createSignal()

		-- In this test, we'll connect two listeners that each try to disconnect
		-- the other. Because the order of listeners firing isn't defined, we
		-- have to be careful to handle either case.

		local disconnectA
		local disconnectB

		local spyA = createSpy(function()
			disconnectB()
		end)

		local spyB = createSpy(function()
			disconnectA()
		end)

		disconnectA = signal:subscribe(spyA.value)
		disconnectB = signal:subscribe(spyB.value)

		signal:fire()

		-- Exactly once listener should have been called.
		expect(spyA.callCount + spyB.callCount).to.equal(1)
	end)
end