local G=(require("\115\117\112\112\111\114\116\046\102\097\099\116\111\114\121")).create local z=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\065\098\105\108\105\116\121")local f=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\105\110\118\111\107\101\114")describe("\100\111\116\097\050\046\065\098\105\108\105\116\121",function()describe("\099\111\110\115\116\114\117\099\116\111\114",function()it("\105\110\105\116\105\097\108\105\122\101\115 \097\116\116\114\105\098\117\116\101\115",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_QUAS,index=13})local p=z(u)assert.equal(f.ABILITY_QUAS,p.name)assert.equal(13,p.index)u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_SUN_STRIKE;index=31})p=z(u)assert.equal(f.ABILITY_SUN_STRIKE,p.name)assert.equal(31,p.index)u=G("\100\111\116\097\095\105\116\101\109",{name="\105\116\101\109\095\098\108\105\110\107"})p=z(u)assert.equal("\105\116\101\109\095\098\108\105\110\107",p.name)assert.equal(nil,p.index)end)end)describe("\100\101\108\101\103\097\116\105\111\110",function()it("\100\101\108\101\103\097\116\101\115 \109\101\116\104\111\100\115 \116\111 \117\110\100\101\114\108\121\105\110\103 \101\110\116\105\116\121",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_QUAS,index=13})local p=z(u)local q={"\071\101\116\068\117\114\097\116\105\111\110";"\071\101\116\083\112\101\099\105\097\108\086\097\108\117\101\070\111\114";"\073\115\073\116\101\109"}for G,z in ipairs(q)do local f=spy.on(u,z)p[z](p);(assert.spy(f)).was.called(1)end end)end)describe("\035\073\115\079\114\098\065\098\105\108\105\116\121",function()describe("\119\105\116\104 \105\116\101\109",function()it("\114\101\116\117\114\110\115 \102\097\108\115\101",function()local f=G("\100\111\116\097\095\105\116\101\109",{name="\105\116\101\109\095\098\108\105\110\107"})local u=z(f)assert.is_false(u:IsOrbAbility())end)end)describe("\119\105\116\104 \110\111\110-\111\114\098 \097\098\105\108\105\116\121",function()it("\114\101\116\117\114\110\115 \102\097\108\115\101",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_SUN_STRIKE,index=13})local p=z(u)assert.is_false(p:IsOrbAbility())end)end)describe("\119\105\116\104 \111\114\098 \097\098\105\108\105\116\121",function()it("\114\101\116\117\114\110\115 \116\114\117\101",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_QUAS,index=13})local p=z(u)assert.is_true(p:IsOrbAbility())end)end)end)describe("\035\073\115\073\110\118\111\099\097\116\105\111\110\065\098\105\108\105\116\121",function()describe("\119\105\116\104 \105\116\101\109",function()it("\114\101\116\117\114\110\115 \102\097\108\115\101",function()local f=G("\100\111\116\097\095\105\116\101\109",{name="\105\116\101\109\095\098\108\105\110\107"})local u=z(f)assert.is_false(u:IsInvocationAbility())end)end)describe("\119\105\116\104 \110\111\110-\111\114\098 \097\098\105\108\105\116\121",function()it("\114\101\116\117\114\110\115 \102\097\108\115\101",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_SUN_STRIKE;index=13})local p=z(u)assert.is_false(p:IsInvocationAbility())end)end)describe("\119\105\116\104 \111\114\098 \097\098\105\108\105\116\121",function()it("\114\101\116\117\114\110\115 \116\114\117\101",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_QUAS;index=13})local p=z(u)assert.is_true(p:IsInvocationAbility())end)end)describe("\119\105\116\104 \105\110\118\111\107\101 \097\098\105\108\105\116\121",function()it("\114\101\116\117\114\110\115 \116\114\117\101",function()local u=G("\100\111\116\097\095\097\098\105\108\105\116\121",{name=f.ABILITY_INVOKE,index=1})local p=z(u)assert.is_true(p:IsInvocationAbility())end)end)end)end)
local create = require("support.factory").create

local Ability = require("invokation.dota2.Ability")

local INVOKER = require("invokation.const.invoker")

describe("dota2.Ability", function()
  describe("constructor", function()
    it("initializes attributes", function()
      local entity = create("dota_ability", { name = INVOKER.ABILITY_QUAS, index = 13 })
      local ability = Ability(entity)

      assert.equal(INVOKER.ABILITY_QUAS, ability.name)
      assert.equal(13, ability.index)

      entity = create("dota_ability", { name = INVOKER.ABILITY_SUN_STRIKE, index = 31 })
      ability = Ability(entity)

      assert.equal(INVOKER.ABILITY_SUN_STRIKE, ability.name)
      assert.equal(31, ability.index)

      entity = create("dota_item", { name = "item_blink" })
      ability = Ability(entity)

      assert.equal("item_blink", ability.name)
      assert.equal(nil, ability.index)
    end)
  end)

  describe("delegation", function()
    it("delegates methods to underlying entity", function()
      local entity = create("dota_ability", { name = INVOKER.ABILITY_QUAS, index = 13 })
      local ability = Ability(entity)
      local delegated = { "GetDuration", "GetSpecialValueFor", "IsItem" }

      for _, method in ipairs(delegated) do
        local spy = spy.on(entity, method)

        ability[method](ability)

        assert.spy(spy).was.called(1)
      end
    end)
  end)

  describe("#IsOrbAbility", function()
    describe("with item", function()
      it("returns false", function()
        local entity = create("dota_item", { name = "item_blink" })
        local ability = Ability(entity)

        assert.is_false(ability:IsOrbAbility())
      end)
    end)

    describe("with non-orb ability", function()
      it("returns false", function()
        local entity = create("dota_ability", { name = INVOKER.ABILITY_SUN_STRIKE, index = 13 })
        local ability = Ability(entity)

        assert.is_false(ability:IsOrbAbility())
      end)
    end)

    describe("with orb ability", function()
      it("returns true", function()
        local entity = create("dota_ability", { name = INVOKER.ABILITY_QUAS, index = 13 })
        local ability = Ability(entity)

        assert.is_true(ability:IsOrbAbility())
      end)
    end)
  end)

  describe("#IsInvocationAbility", function()
    describe("with item", function()
      it("returns false", function()
        local entity = create("dota_item", { name = "item_blink" })
        local ability = Ability(entity)

        assert.is_false(ability:IsInvocationAbility())
      end)
    end)

    describe("with non-orb ability", function()
      it("returns false", function()
        local entity = create("dota_ability", { name = INVOKER.ABILITY_SUN_STRIKE, index = 13 })
        local ability = Ability(entity)

        assert.is_false(ability:IsInvocationAbility())
      end)
    end)

    describe("with orb ability", function()
      it("returns true", function()
        local entity = create("dota_ability", { name = INVOKER.ABILITY_QUAS, index = 13 })
        local ability = Ability(entity)

        assert.is_true(ability:IsInvocationAbility())
      end)
    end)

    describe("with invoke ability", function()
      it("returns true", function()
        local entity = create("dota_ability", { name = INVOKER.ABILITY_INVOKE, index = 1 })
        local ability = Ability(entity)

        assert.is_true(ability:IsInvocationAbility())
      end)
    end)
  end)
end)
