local U=(require("\115\117\112\112\111\114\116\046\102\097\099\116\111\114\121")).create local e=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\117\110\105\116\115")local Q=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\068\117\109\109\121\084\097\114\103\101\116")describe("\100\111\116\097\050\046\068\117\109\109\121\084\097\114\103\101\116",function()local function R()local Q=0 stub.new(e,"\067\114\101\097\116\101",function()Q=Q+1 return U("\100\111\116\097\095\117\110\105\116",{name=e.DUMMY_TARGET,__test_index=Q})end)end local k=U("\101\110\116\105\116\121",{name=e.DUMMY_TARGET_SPAWN})before_each(function()stub.new(Entities,"\070\105\110\100\066\121\078\097\109\101",function()return k end)R()stub.new(e,"\068\101\115\116\114\111\121",function()return nil end)end)after_each(function()Entities.FindByName:revert()e.Create:revert()e.Destroy:revert()end)describe("\099\111\110\115\116\114\117\099\116\111\114",function()it("\102\105\110\100\115 \097\110\100 \115\101\116\115 \116\104\101 \115\112\097\119\110 \112\111\105\110\116 \101\110\116\105\116\121",function()local U=Q({spawn=false})assert.equal(k,U.spawn)end)end)describe("\035\073\115\065\108\105\118\101",function()it("\114\101\116\117\114\110\115 \116\114\117\101 \105\102 \116\104\101 \100\117\109\109\121 \117\110\105\116 \101\120\105\115\116\115",function()local U=Q({spawn=true})assert.is_true(U:IsAlive())end)it("\114\101\116\117\114\110\115 \102\097\108\115\101 \105\102 \116\104\101 \100\117\109\109\121 \117\110\105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local U=Q({spawn=false})assert.is_false(U:IsAlive())end)end)describe("\035\073\115\068\101\097\100",function()it("\114\101\116\117\114\110\115 \102\097\108\115\101 \105\102 \116\104\101 \100\117\109\109\121 \117\110\105\116 \101\120\105\115\116\115",function()local U=Q({spawn=true})assert.is_false(U:IsDead())end)it("\114\101\116\117\114\110\115 \116\114\117\101 \105\102 \116\104\101 \100\117\109\109\121 \117\110\105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local U=Q({spawn=false})assert.is_true(U:IsDead())end)end)describe("\035\083\112\097\119\110",function()it("\100\111\101\115 \078\079\084 \115\112\097\119\110 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \101\120\105\115\116\115",function()local U=Q({spawn=true})assert.not_nil(U.entity)assert.equal(1,U.entity.__test_index)U:Spawn()assert.not_nil(U.entity)assert.equal(1,U.entity.__test_index);(assert.spy(e.Create)).was.called(1);(assert.spy(e.Create)).was.called_with(e.DUMMY_TARGET,{location=k:GetAbsOrigin();team=DOTA_TEAM_BADGUYS})end)it("\115\112\097\119\110\115 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local U=Q({spawn=false})assert.is_nil(U.entity)U:Spawn()assert.not_nil(U.entity)assert.equal(1,U.entity.__test_index);(assert.spy(e.Create)).was.called(1);(assert.spy(e.Create)).was.called_with(e.DUMMY_TARGET,{location=k:GetAbsOrigin();team=DOTA_TEAM_BADGUYS})end)end)describe("\035\075\105\108\108",function()it("\100\111\101\115 \078\079\084 \107\105\108\108 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local U=Q({spawn=false})assert.is_nil(U.entity)U:Kill()assert.is_nil(U.entity);(assert.spy(e.Destroy)).was.not_called()end)it("\107\105\108\108\115 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \101\120\105\115\116\115",function()local U=Q({spawn=true})assert.not_nil(U.entity)U:Kill()assert.is_nil(U.entity);(assert.spy(e.Destroy)).was.called(1)end)end)describe("\035\082\101\115\101\116",function()it("\115\112\097\119\110\115 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \100\111\101\115\110\'\116 \101\120\105\115\116",function()local U=Q({spawn=false})local e=spy.on(U,"\075\105\108\108")local R=spy.on(U,"\083\112\097\119\110")assert.is_nil(U.entity)U:Reset()assert.not_nil(U.entity)assert.equal(1,U.entity.__test_index);(assert.spy(e)).was.called(1);(assert.spy(R)).was.called(1)end)it("\114\101\115\112\097\119\110\115 \116\104\101 \100\117\109\109\121 \117\110\105\116 \105\102 \105\116 \101\120\105\115\116\115",function()local U=Q({spawn=true})local e=spy.on(U,"\075\105\108\108")local R=spy.on(U,"\083\112\097\119\110")assert.not_nil(U.entity)assert.equal(1,U.entity.__test_index)U:Reset()assert.not_nil(U.entity)assert.equal(2,U.entity.__test_index);(assert.spy(e)).was.called(1);(assert.spy(R)).was.called(1)end)end)end)
local create = require("support.factory").create

local Units = require("invokation.dota2.units")
local DummyTarget = require("invokation.dota2.DummyTarget")

describe("dota2.DummyTarget", function()
  local function stubUnitsCreate()
    local i = 0

    stub.new(Units, "Create", function()
      i = i + 1
      return create("dota_unit", { name = Units.DUMMY_TARGET, __test_index = i })
    end)
  end

  local spawn = create("entity", { name = Units.DUMMY_TARGET_SPAWN })

  before_each(function()
    stub.new(Entities, "FindByName", function()
      return spawn
    end)

    stubUnitsCreate()

    stub.new(Units, "Destroy", function()
      return nil
    end)
  end)

  after_each(function()
    -- selene: allow(incorrect_standard_library_use)
    Entities.FindByName:revert()
    Units.Create:revert()
    Units.Destroy:revert()
  end)

  describe("constructor", function()
    it("finds and sets the spawn point entity", function()
      local dummy = DummyTarget({ spawn = false })

      assert.equal(spawn, dummy.spawn)
    end)
  end)

  describe("#IsAlive", function()
    it("returns true if the dummy unit exists", function()
      local dummy = DummyTarget({ spawn = true })

      assert.is_true(dummy:IsAlive())
    end)

    it("returns false if the dummy unit doesn't exist", function()
      local dummy = DummyTarget({ spawn = false })

      assert.is_false(dummy:IsAlive())
    end)
  end)

  describe("#IsDead", function()
    it("returns false if the dummy unit exists", function()
      local dummy = DummyTarget({ spawn = true })

      assert.is_false(dummy:IsDead())
    end)

    it("returns true if the dummy unit doesn't exist", function()
      local dummy = DummyTarget({ spawn = false })

      assert.is_true(dummy:IsDead())
    end)
  end)

  describe("#Spawn", function()
    it("does NOT spawn the dummy unit if it exists", function()
      local dummy = DummyTarget({ spawn = true })

      assert.not_nil(dummy.entity)
      assert.equal(1, dummy.entity.__test_index)

      dummy:Spawn()

      assert.not_nil(dummy.entity)
      assert.equal(1, dummy.entity.__test_index)
      assert.spy(Units.Create).was.called(1)
      assert.spy(Units.Create).was.called_with(Units.DUMMY_TARGET, {
        location = spawn:GetAbsOrigin(),
        team = DOTA_TEAM_BADGUYS,
      })
    end)

    it("spawns the dummy unit if it doesn't exist", function()
      local dummy = DummyTarget({ spawn = false })

      assert.is_nil(dummy.entity)

      dummy:Spawn()

      assert.not_nil(dummy.entity)
      assert.equal(1, dummy.entity.__test_index)
      assert.spy(Units.Create).was.called(1)
      assert.spy(Units.Create).was.called_with(Units.DUMMY_TARGET, {
        location = spawn:GetAbsOrigin(),
        team = DOTA_TEAM_BADGUYS,
      })
    end)
  end)

  describe("#Kill", function()
    it("does NOT kill the dummy unit if it doesn't exist", function()
      local dummy = DummyTarget({ spawn = false })

      assert.is_nil(dummy.entity)

      dummy:Kill()

      assert.is_nil(dummy.entity)
      assert.spy(Units.Destroy).was.not_called()
    end)

    it("kills the dummy unit if it exists", function()
      local dummy = DummyTarget({ spawn = true })

      assert.not_nil(dummy.entity)

      dummy:Kill()

      assert.is_nil(dummy.entity)
      assert.spy(Units.Destroy).was.called(1)
    end)
  end)

  describe("#Reset", function()
    it("spawns the dummy unit if it doesn't exist", function()
      local dummy = DummyTarget({ spawn = false })
      local killSpy = spy.on(dummy, "Kill")
      local spawnSpy = spy.on(dummy, "Spawn")

      assert.is_nil(dummy.entity)

      dummy:Reset()

      assert.not_nil(dummy.entity)
      assert.equal(1, dummy.entity.__test_index)
      assert.spy(killSpy).was.called(1)
      assert.spy(spawnSpy).was.called(1)
    end)

    it("respawns the dummy unit if it exists", function()
      local dummy = DummyTarget({ spawn = true })
      local killSpy = spy.on(dummy, "Kill")
      local spawnSpy = spy.on(dummy, "Spawn")

      assert.not_nil(dummy.entity)
      assert.equal(1, dummy.entity.__test_index)

      dummy:Reset()

      assert.not_nil(dummy.entity)
      assert.equal(2, dummy.entity.__test_index)
      assert.spy(killSpy).was.called(1)
      assert.spy(spawnSpy).was.called(1)
    end)
  end)
end)
