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\099\111\109\098\111\115\046\067\111\109\098\111")local f=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\109\098\111\115\046\099\111\109\109\117\110\105\099\097\116\105\111\110")local u=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\099\117\115\116\111\109\095\101\118\101\110\116\115")describe("\099\111\109\098\111\115\046\099\111\109\109\117\110\105\099\097\116\105\111\110",function()local p local q={}local c=G("\097\098\105\108\105\116\121",{name="\097\098\105\108\105\116\121"})local w={id=13,sequence={{id=1,name="\097\098\105\108\105\116\121"}}}local g local function Q()g=g+1 return g end before_each(function()p=z(w)g=0 spy.on(u,"\083\101\110\100\080\108\097\121\101\114")end)after_each(function()u.SendPlayer:revert()end)describe("\046\115\101\110\100\065\098\105\108\105\116\121\085\115\101\100",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G={ability="\097\098\105\108\105\116\121"}f.sendAbilityUsed(q,c);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBAT_LOG_ABILITY_USED,q,G)end)end)describe("\046\115\101\110\100\083\116\097\114\116\101\100",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G={id=13;next={1}}f.sendStarted(q,p);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_STARTED,q,G)end)end)describe("\046\115\101\110\100\083\116\111\112\112\101\100",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G={id=13}f.sendStopped(q,p);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_STOPPED,q,G)end)end)describe("\046\115\101\110\100\073\110\080\114\111\103\114\101\115\115",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G={id=13}f.sendInProgress(q,p);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_IN_PROGRESS,q,G)end)end)describe("\046\115\101\110\100\080\114\111\103\114\101\115\115",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()assert.is_true(p:Progress(c))assert.equal(123,p:IncrementDamage(123))local G={id=13,metrics={count=1;damage=123,duration=nil};next={}}f.sendProgress(q,p);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_PROGRESS,q,G)end)end)describe("\046\115\101\110\100\083\116\101\112\069\114\114\111\114",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G={id=13;expected={1},ability="\097\098\105\108\105\116\121"}f.sendStepError(q,p,c);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_STEP_ERROR,q,G)end)end)describe("\046\115\101\110\100\080\114\101\070\105\110\105\115\104",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local p=G("\097\098\105\108\105\116\121",{name="\097\098\105\108\105\116\121",AbilityDuration=3.5})local c=z(w,{clock=Q})assert.is_true(c:Progress(p))assert.equal(123,c:IncrementDamage(123))assert.is_true(c:PreFinish())local g={id=13;metrics={count=1;damage=123;duration=nil};wait=2.5}f.sendPreFinish(q,c);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_PRE_FINISH,q,g)end)end)describe("\046\115\101\110\100\070\105\110\105\115\104\101\100",function()it("\115\101\110\100\115 \099\117\115\116\111\109 \101\118\101\110\116",function()local G=z(w,{clock=Q})assert.is_true(G:Progress(c))assert.equal(123,G:IncrementDamage(123))assert.is_true(G:PreFinish())assert.is_true(G:Finish())local p={id=13,metrics={count=1,damage=123;duration=3}}f.sendFinished(q,G);(assert.spy(u.SendPlayer)).was.called_with(u.EVENT_COMBO_FINISHED,q,p)end)end)end)
local create = require("support.factory").create

local Combo = require("invokation.combos.Combo")
local CombosComm = require("invokation.combos.communication")
local CustomEvents = require("invokation.dota2.custom_events")

describe("combos.communication", function()
  local combo
  local player = {}
  local ability = create("ability", { name = "ability" })

  local comboSpec = { id = 13, sequence = { { id = 1, name = "ability" } } }

  local clockIdx
  local function clock()
    clockIdx = clockIdx + 1
    return clockIdx
  end

  before_each(function()
    combo = Combo(comboSpec)
    clockIdx = 0
    spy.on(CustomEvents, "SendPlayer")
  end)

  after_each(function()
    CustomEvents.SendPlayer:revert()
  end)

  describe(".sendAbilityUsed", function()
    it("sends custom event", function()
      local payload = { ability = "ability" }

      CombosComm.sendAbilityUsed(player, ability)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBAT_LOG_ABILITY_USED, player, payload)
    end)
  end)

  describe(".sendStarted", function()
    it("sends custom event", function()
      local payload = { id = 13, next = { 1 } }

      CombosComm.sendStarted(player, combo)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_STARTED, player, payload)
    end)
  end)

  describe(".sendStopped", function()
    it("sends custom event", function()
      local payload = { id = 13 }

      CombosComm.sendStopped(player, combo)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_STOPPED, player, payload)
    end)
  end)

  describe(".sendInProgress", function()
    it("sends custom event", function()
      local payload = { id = 13 }

      CombosComm.sendInProgress(player, combo)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_IN_PROGRESS, player, payload)
    end)
  end)

  describe(".sendProgress", function()
    it("sends custom event", function()
      assert.is_true(combo:Progress(ability))
      assert.equal(123, combo:IncrementDamage(123))

      local payload = { id = 13, metrics = { count = 1, damage = 123, duration = nil }, next = {} }

      CombosComm.sendProgress(player, combo)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_PROGRESS, player, payload)
    end)
  end)

  describe(".sendStepError", function()
    it("sends custom event", function()
      local payload = { id = 13, expected = { 1 }, ability = "ability" }

      CombosComm.sendStepError(player, combo, ability)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_STEP_ERROR, player, payload)
    end)
  end)

  describe(".sendPreFinish", function()
    it("sends custom event", function()
      local abilityWithWait = create("ability", { name = "ability", AbilityDuration = 3.5 })
      local comboWithDelay = Combo(comboSpec, { clock = clock })

      assert.is_true(comboWithDelay:Progress(abilityWithWait))
      assert.equal(123, comboWithDelay:IncrementDamage(123))
      assert.is_true(comboWithDelay:PreFinish())

      local payload = { id = 13, metrics = { count = 1, damage = 123, duration = nil }, wait = 2.5 }

      CombosComm.sendPreFinish(player, comboWithDelay)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_PRE_FINISH, player, payload)
    end)
  end)

  describe(".sendFinished", function()
    it("sends custom event", function()
      local comboWithDelay = Combo(comboSpec, { clock = clock })

      assert.is_true(comboWithDelay:Progress(ability))
      assert.equal(123, comboWithDelay:IncrementDamage(123))
      assert.is_true(comboWithDelay:PreFinish())
      assert.is_true(comboWithDelay:Finish())

      local payload = { id = 13, metrics = { count = 1, damage = 123, duration = 3 } }

      CombosComm.sendFinished(player, comboWithDelay)

      assert.spy(CustomEvents.SendPlayer).was.called_with(CustomEvents.EVENT_COMBO_FINISHED, player, payload)
    end)
  end)
end)
