return function()local f=require(script.Parent.Parent.FunctionUtils.void)local j=require(script.Parent)it("\115\104\111\117\108\100 \098\101 \097 \116\097\098\108\101",function(f)(expect(j)).to.be.a("\116\097\098\108\101")end)it("\115\104\111\117\108\100 \110\111\116 \099\111\110\116\097\105\110 \097 \109\101\116\097\116\097\098\108\101",function()(expect(getmetatable(j))).to.equal(nil)end)it("\115\104\111\117\108\100 \116\104\114\111\119 \097\110 \101\114\114\111\114 \111\110 \097\116\116\101\109\112\116 \116\111 \109\111\100\105\102\121 \116\104\101 \101\120\112\111\114\116 \116\097\098\108\101",function()(expect(function()j._={}end)).to.throw();(expect(function()setmetatable(j,{})end)).to.throw()end)it("\115\104\111\117\108\100 \115\117\112\112\111\114\116 \114\101\115\116\114\105\099\116\101\100 \098\101\104\097\118\105\111\117\114",function()(expect(function()local f={}function f.__index(J,f)if f=="\099\111\110\110\101\099\116"or f=="\119\097\105\116"then return j.prototype[f]end end function f.new()return setmetatable({},f)end local J=f.new()assert(not pcall(function()J:fire()end))assert(not pcall(function()J:destroy()end))task.defer(function()j.prototype.fire(J,"\102\111\111")end)J:connect(function(f)assert(f=="\102\111\111")end)assert(J:wait()=="\102\111\111")end)).never.throw()end)describe("\058\111\110\099\101\040\041",function()it("\115\104\111\117\108\100 \100\105\115\099\111\110\110\101\099\116 \116\104\101 \099\111\110\110\101\099\116\105\111\110 \098\101\102\111\114\101 \105\110\118\111\107\105\110\103 \116\104\101 \099\097\108\108\098\097\099\107",function()(expect(function()local f=coroutine.running()local J=j.new()local g=nil g=J:once(function()task.spawn(f)end)task.defer(function()J:fire()end)coroutine.yield()assert(not g.connected)end)).never.throw()end)end)end
return function()
	local void = require(script.Parent.Parent.FunctionUtils.void)

	local Signal = require(script.Parent)

	it("should be a table", function(n)
		expect(Signal).to.be.a("table")
	end)

	it("should not contain a metatable", function()
		expect(getmetatable(Signal)).to.equal(nil)
	end)

	it("should throw an error on attempt to modify the export table", function()
		expect(function()
			Signal._ = {}
		end).to.throw()

		expect(function()
			setmetatable(Signal, {})
		end).to.throw()
	end)

	it("should support restricted behaviour", function()
		expect(function()
			local RestrictedSignal = {}

			function RestrictedSignal:__index(index)
				if index == "connect" or index == "wait" then
					return Signal.prototype[index]
				end
			end

			function RestrictedSignal.new()
				return setmetatable({}, RestrictedSignal)
			end

			local newSignal = RestrictedSignal.new()

			assert(not pcall(function()
				newSignal:fire()
			end))

			assert(not pcall(function()
				newSignal:destroy()
			end))

			task.defer(function()
				Signal.prototype.fire(newSignal, "foo")
			end)

			newSignal:connect(function(value)
				assert(value == "foo")
			end)

			assert(newSignal:wait() == "foo")
		end).never.throw()
	end)

	describe(":once()", function()
		it("should disconnect the connection before invoking the callback", function()
			expect(function()
				local resolveAwaitThread = coroutine.running()
				local signal = Signal.new()
				local connection = nil

				connection = signal:once(function()
					task.spawn(resolveAwaitThread)
				end)

				task.defer(function()
					signal:fire()
				end)

				coroutine.yield()

				assert(not connection.connected)
			end).never.throw()
		end)
	end)
end
