local G=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\109\098\111\115\046\080\108\097\121\101\114\083\116\097\116\101\115")describe("\080\108\097\121\101\114\083\116\097\116\101\115",function()describe("\035\095\095\105\110\100\101\120",function()it("\099\114\101\097\116\101\115 \097 \110\101\119 \112\108\097\121\101\114 \115\116\097\116\101 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116 \121\101\116",function()local z={GetPlayerID=spy.new(function()return 1 end)}local f={GetPlayerID=spy.new(function()return 2 end)}local u=G()assert.is_nil(u.states[1])local p=u[z]assert.same({},p)assert.equal(u.states[1],p);(assert.spy(z.GetPlayerID)).was_called(1)assert.is_nil(u.states[2])local q=u[f]assert.same({},q)assert.equal(u.states[2],q);(assert.spy(f.GetPlayerID)).was_called(1)assert.not_equal(p,q)end)it("\114\101\116\117\114\110\115 \097 \112\114\101\118\105\111\117\115\108\121 \099\114\101\097\116\101\100 \115\116\097\116\101",function()local z={GetPlayerID=spy.new(function()return 1 end)}local f=G()assert.is_nil(f.states[1])local u=f[z]assert.same({},u)assert.equal(f.states[1],u);(assert.spy(z.GetPlayerID)).was_called(1)z.GetPlayerID:clear()local p=f[z]assert.same({},p)assert.equal(u,p)assert.equal(f.states[1],p);(assert.spy(z.GetPlayerID)).was_called(1)p.key1="\118\097\108\117\101"assert.equal("\118\097\108\117\101",u.key1)z.GetPlayerID:clear()local q=f[z]assert.same({key1="\118\097\108\117\101"},q)assert.equal(u,p,q)assert.equal(f.states[1],q);(assert.spy(z.GetPlayerID)).was_called(1)q.key2=13 assert.same({key1="\118\097\108\117\101",key2=13},u)assert.same({key1="\118\097\108\117\101";key2=13},p)assert.same({key1="\118\097\108\117\101";key2=13},q)end)end)end)
local PlayerStates = require("invokation.combos.PlayerStates")

describe("PlayerStates", function()
  describe("#__index", function()
    it("creates a new player state if it doesn't exist yet", function()
      local player1 = {
        GetPlayerID = spy.new(function()
          return 1
        end),
      }

      local player2 = {
        GetPlayerID = spy.new(function()
          return 2
        end),
      }

      local states = PlayerStates()

      assert.is_nil(states.states[1])

      local state1 = states[player1]

      assert.same({}, state1)
      assert.equal(states.states[1], state1)
      assert.spy(player1.GetPlayerID).was_called(1)

      assert.is_nil(states.states[2])

      local state2 = states[player2]

      assert.same({}, state2)
      assert.equal(states.states[2], state2)
      assert.spy(player2.GetPlayerID).was_called(1)

      assert.not_equal(state1, state2)
    end)

    it("returns a previously created state", function()
      local player = {
        GetPlayerID = spy.new(function()
          return 1
        end),
      }

      local states = PlayerStates()

      assert.is_nil(states.states[1])

      local state1 = states[player]

      assert.same({}, state1)
      assert.equal(states.states[1], state1)
      assert.spy(player.GetPlayerID).was_called(1)

      player.GetPlayerID:clear()

      local state2 = states[player]

      assert.same({}, state2)
      assert.equal(state1, state2)
      assert.equal(states.states[1], state2)
      assert.spy(player.GetPlayerID).was_called(1)

      state2.key1 = "value"

      assert.equal("value", state1.key1)

      player.GetPlayerID:clear()

      local state3 = states[player]

      assert.same({ key1 = "value" }, state3)
      assert.equal(state1, state2, state3)
      assert.equal(states.states[1], state3)
      assert.spy(player.GetPlayerID).was_called(1)

      state3.key2 = 13

      assert.same({ key1 = "value", key2 = 13 }, state1)

      assert.same({ key1 = "value", key2 = 13 }, state2)

      assert.same({ key1 = "value", key2 = 13 }, state3)
    end)
  end)
end)
