return function()local m=require(script.Parent.Server)local q=require(script.Parent.Client)local x=require(script.Parent.RemoteEventClient)local L=require(script.Parent.RemoteFunctionClient)describe("\067\108\105\101\110\116\058\103\101\116\082\101\109\111\116\101\069\118\101\110\116",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \099\108\105\101\110\116 \115\105\100\101\100 \082\101\109\111\116\101\069\118\101\110\116 \105\102 \105\116 \101\120\105\115\116\115",function()local q=m.new()local L=q:connect("\117\115\101\114")q:createRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116");(expect(L:getRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116"))).to.be.a("\116\097\098\108\101");(expect(getmetatable(L:getRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116")))).to.equal(x)q:destroy()end)it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local q=m.new()local x=q:connect("\117\115\101\114");(expect(function()x:getRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116")end)).to.throw()q:destroy()end)end)describe("\067\108\105\101\110\116\058\103\101\116\082\101\109\111\116\101\070\117\110\099\116\105\111\110",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \099\108\105\101\110\116 \115\105\100\101\100 \082\101\109\111\116\101\070\117\110\099\116\105\111\110 \105\102 \105\116 \101\120\105\115\116\115",function()local q=m.new()local x=q:connect("\117\115\101\114")q:createRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110");(expect(x:getRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110"))).to.be.a("\116\097\098\108\101");(expect(getmetatable(x:getRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110")))).to.equal(L)q:destroy()end)it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local q=m.new()local x=q:connect("\117\115\101\114");(expect(function()x:getRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110")end)).to.throw()q:destroy()end)end)describe("\067\108\105\101\110\116\058\100\105\115\099\111\110\110\101\099\116",function()it("\115\104\111\117\108\100 \115\101\116 \099\111\110\110\101\099\116\101\100 \102\105\101\108\100 \115\101\116 \116\111 \102\097\108\115\101",function()local q=m.new()local x=q:connect("\117\115\101\114")x:disconnect();(expect(x.connected)).to.equal(false)q:destroy()end)it("\115\104\111\117\108\100 \110\111\116 \101\120\105\115\116 \111\110 \115\101\114\118\101\114 \097\110\121\109\111\114\101",function()local q=m.new()local x=q:connect("\117\115\101\114");(expect(q:getClient("\117\115\101\114"))).to.be.ok()x:disconnect();(expect(q:getClient("\117\115\101\114"))).to.equal(nil)q:destroy()end)end)describe("\067\108\105\101\110\116\058\109\097\112\082\101\109\111\116\101\069\118\101\110\116\115",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \100\105\099\116\105\111\110\097\114\121 \116\104\097\116 \109\097\112\115 \116\104\101 \114\101\109\111\116\101\069\118\101\110\116 \110\097\109\101 \116\111 \116\104\101 \111\098\106\101\099\116 \105\102 \110\111 \102\117\110\099\116\105\111\110 \105\115 \112\097\115\115\101\100",function()local q=m.new()local x=q:connect("\117\115\101\114")q:createRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\049")q:createRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\050")local L=x:mapRemoteEvents();(expect(L.remoteEvent1)).to.be.ok();(expect(L.remoteEvent2)).to.be.ok();(expect(L.remoteEvent1)).to.equal(x:getRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\049"));(expect(L.remoteEvent2)).to.equal(x:getRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\050"))q:destroy()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \100\105\099\116\105\111\110\097\114\121 \116\104\097\116 \105\115 \112\114\111\112\101\114\108\121 \109\097\112\112\101\100 \105\102 \097 \102\117\110\099\116\105\111\110 \105\115 \112\097\115\115\101\100",function()local q=m.new()local x=q:connect("\117\115\101\114")q:createRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\049")q:createRemoteEvent("\114\101\109\111\116\101\069\118\101\110\116\050")local L=x:mapRemoteEvents(function(m,q)return string.upper(m),typeof(q)end);(expect(L.remoteEvent1)).to.never.be.ok();(expect(L.remoteEvent2)).to.never.be.ok();(expect(L.REMOTEEVENT1)).to.equal("\116\097\098\108\101");(expect(L.REMOTEEVENT2)).to.equal("\116\097\098\108\101")q:destroy()end)end)describe("\067\108\105\101\110\116\058\109\097\112\082\101\109\111\116\101\070\117\110\099\116\105\111\110\115",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \100\105\099\116\105\111\110\097\114\121 \116\104\097\116 \109\097\112\115 \116\104\101 \114\101\109\111\116\101\070\117\110\099\116\105\111\110 \110\097\109\101 \116\111 \116\104\101 \111\098\106\101\099\116 \105\102 \110\111 \102\117\110\099\116\105\111\110 \105\115 \112\097\115\115\101\100",function()local q=m.new()local x=q:connect("\117\115\101\114")q:createRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\049")q:createRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\050")local L=x:mapRemoteFunctions();(expect(L.remoteFunction1)).to.be.ok();(expect(L.remoteFunction2)).to.be.ok();(expect(L.remoteFunction1)).to.equal(x:getRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\049"));(expect(L.remoteFunction2)).to.equal(x:getRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\050"))q:destroy()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \100\105\099\116\105\111\110\097\114\121 \116\104\097\116 \105\115 \112\114\111\112\101\114\108\121 \109\097\112\112\101\100 \105\102 \097 \102\117\110\099\116\105\111\110 \105\115 \112\097\115\115\101\100",function()local q=m.new()local x=q:connect("\117\115\101\114")q:createRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\049")q:createRemoteFunction("\114\101\109\111\116\101\070\117\110\099\116\105\111\110\050")local L=x:mapRemoteFunctions(function(m,q)return string.upper(m),typeof(q)end);(expect(L.remoteFunction1)).to.never.be.ok();(expect(L.remoteFunction2)).to.never.be.ok();(expect(L.REMOTEFUNCTION1)).to.equal("\116\097\098\108\101");(expect(L.REMOTEFUNCTION2)).to.equal("\116\097\098\108\101")q:destroy()end)end)describe("\067\108\105\101\110\116\058\100\101\115\116\114\111\121",function()it("\115\104\111\117\108\100 \100\105\115\099\111\110\101\099\116 \116\104\101 \099\108\105\101\110\116",function()local q=m.new()local x=q:connect("\117\115\101\114")x:destroy();(expect(x.connected)).to.equal(false)q:destroy()end)it("\115\104\111\117\108\100 \115\101\116 \100\101\115\116\114\111\121\101\100 \102\105\101\108\100 \116\111 \116\114\117\101",function()local q=m.new()local x=q:connect("\117\115\101\114")x:destroy();(expect(x.destroyed)).to.equal(true)q:destroy()end)end)end
return function()
    local Server = require(script.Parent.Server)
    local Client = require(script.Parent.Client)

    local RemoteEventClient = require(script.Parent.RemoteEventClient)
    local RemoteFunctionClient = require(script.Parent.RemoteFunctionClient)

    describe("Client:getRemoteEvent", function()
        it("should return the client sided RemoteEvent if it exists", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteEvent("remoteEvent")

            expect(client:getRemoteEvent("remoteEvent")).to.be.a("table")
            expect(getmetatable(client:getRemoteEvent("remoteEvent"))).to.equal(RemoteEventClient)

            server:destroy()
        end)

        it("should throw if it doesn't exist", function()
            local server = Server.new()
            local client = server:connect("user")

            expect(function()
                client:getRemoteEvent("remoteEvent")
            end).to.throw()

            server:destroy()
        end)
    end)

    describe("Client:getRemoteFunction", function()
        it("should return the client sided RemoteFunction if it exists", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteFunction("remoteFunction")
            
            expect(client:getRemoteFunction("remoteFunction")).to.be.a("table")
            expect(getmetatable(client:getRemoteFunction("remoteFunction"))).to.equal(RemoteFunctionClient)

            server:destroy()
        end)

        it("should throw if it doesn't exist", function()
            local server = Server.new()
            local client = server:connect("user")

            expect(function()
                client:getRemoteFunction("remoteFunction")
            end).to.throw()

            server:destroy()
        end)
    end)

    describe("Client:disconnect", function()
        it("should set connected field set to false", function()
            local server = Server.new()
            local client = server:connect("user")

            client:disconnect()

            expect(client.connected).to.equal(false)

            server:destroy()
        end)

        it("should not exist on server anymore", function()
            local server = Server.new()
            local client = server:connect("user")

            expect(server:getClient("user")).to.be.ok()

            client:disconnect()
            
            expect(server:getClient("user")).to.equal(nil)

            server:destroy()
        end)
    end)

    describe("Client:mapRemoteEvents", function()
        it("should return a dictionary that maps the remoteEvent name to the object if no function is passed", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteEvent("remoteEvent1")
            server:createRemoteEvent("remoteEvent2")

            local map = client:mapRemoteEvents()

            expect(map.remoteEvent1).to.be.ok()
            expect(map.remoteEvent2).to.be.ok()

            expect(map.remoteEvent1).to.equal(client:getRemoteEvent("remoteEvent1"))
            expect(map.remoteEvent2).to.equal(client:getRemoteEvent("remoteEvent2"))

            server:destroy()
        end)

        it("should return a dictionary that is properly mapped if a function is passed", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteEvent("remoteEvent1")
            server:createRemoteEvent("remoteEvent2")

            local map = client:mapRemoteEvents(function(name, remoteEvent)
                return string.upper(name), typeof(remoteEvent)
            end)

            expect(map.remoteEvent1).to.never.be.ok()
            expect(map.remoteEvent2).to.never.be.ok()

            expect(map.REMOTEEVENT1).to.equal("table")
            expect(map.REMOTEEVENT2).to.equal("table")

            server:destroy()
        end)
    end)

    describe("Client:mapRemoteFunctions", function()
        it("should return a dictionary that maps the remoteFunction name to the object if no function is passed", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteFunction("remoteFunction1")
            server:createRemoteFunction("remoteFunction2")

            local map = client:mapRemoteFunctions()

            expect(map.remoteFunction1).to.be.ok()
            expect(map.remoteFunction2).to.be.ok()

            expect(map.remoteFunction1).to.equal(client:getRemoteFunction("remoteFunction1"))
            expect(map.remoteFunction2).to.equal(client:getRemoteFunction("remoteFunction2"))

            server:destroy()
        end)

        it("should return a dictionary that is properly mapped if a function is passed", function()
            local server = Server.new()
            local client = server:connect("user")

            server:createRemoteFunction("remoteFunction1")
            server:createRemoteFunction("remoteFunction2")

            local map = client:mapRemoteFunctions(function(name, remoteFunction)
                return string.upper(name), typeof(remoteFunction)
            end)

            expect(map.remoteFunction1).to.never.be.ok()
            expect(map.remoteFunction2).to.never.be.ok()

            expect(map.REMOTEFUNCTION1).to.equal("table")
            expect(map.REMOTEFUNCTION2).to.equal("table")

            server:destroy()
        end)
    end)


    describe("Client:destroy", function()
        it("should disconect the client", function()
            local server = Server.new()
            local client = server:connect("user")

            client:destroy()

            expect(client.connected).to.equal(false)

            server:destroy()
        end)

        it("should set destroyed field to true", function()
            local server = Server.new()
            local client = server:connect("user")

            client:destroy()

            expect(client.destroyed).to.equal(true)

            server:destroy()
        end)
    end)
end