import { describe, expect, it } from "vitest"; import { WOW335_SHAMAN_FLURRY_AURA_TAG, WOW335_SHAMAN_FLURRY_DURATION_MS, WOW335_SHAMAN_FLURRY_TALENT_ID, wow335ShamanFlurryApplyProc, wow335ShamanFlurryConsumeSwingCharge, wow335ShamanFlurryGeneratedSource, wow335ShamanFlurryProfileForRank, wow335ShamanFlurryShouldProc, } from "./wow335ShamanFlurryRuntime"; describe("WoW 3.3.5 Shaman Flurry source model", () => { it("uses the local generated Flurry rank rows and their displayed values", () => { const talent = wow335ShamanFlurryGeneratedSource(); expect(talent).toMatchObject({ id: WOW335_SHAMAN_FLURRY_TALENT_ID, name: "Flurry", treeId: "shaman-enhancement", rankSpellIds: [16256, 16281, 16282], }); expect(talent!.rankDescriptions).toEqual([ expect.stringContaining("melee attack speed by 4% for your next 3 swings"), expect.stringContaining("melee attack speed by 6% for your next 3 swings"), expect.stringContaining("melee attack speed by 10% for your next 3 swings"), ]); expect([1, 2, 3].map(wow335ShamanFlurryProfileForRank)).toEqual([ { rank: 1, meleeHastePercent: 4, swingCharges: 3 }, { rank: 2, meleeHastePercent: 6, swingCharges: 3 }, { rank: 3, meleeHastePercent: 10, swingCharges: 3 }, ]); }); it("normalizes ranks and returns no profile when no rank is trained", () => { expect(wow335ShamanFlurryProfileForRank(0)).toBeNull(); expect(wow335ShamanFlurryProfileForRank(-1)).toBeNull(); expect(wow335ShamanFlurryProfileForRank(Number.NaN)).toBeNull(); expect(wow335ShamanFlurryProfileForRank(99)).toEqual({ rank: 3, meleeHastePercent: 10, swingCharges: 3, }); }); it("triggers only for a landed melee critical strike with a trained rank", () => { const landedMeleeCritical = { attackKind: "melee" as const, landed: true, critical: true }; expect(wow335ShamanFlurryShouldProc(1, landedMeleeCritical)).toBe(true); expect(wow335ShamanFlurryShouldProc(0, landedMeleeCritical)).toBe(false); expect(wow335ShamanFlurryShouldProc(1, { ...landedMeleeCritical, landed: false })).toBe(false); expect(wow335ShamanFlurryShouldProc(1, { ...landedMeleeCritical, critical: false })).toBe(false); expect(wow335ShamanFlurryShouldProc(1, { ...landedMeleeCritical, attackKind: "spell" })).toBe(false); expect(wow335ShamanFlurryShouldProc(1, { ...landedMeleeCritical, attackKind: "ranged" })).toBe(false); }); it("keeps the tooltip display value distinct from the raw rank-two aura payload", () => { const talent = wow335ShamanFlurryGeneratedSource()!; expect(wow335ShamanFlurryProfileForRank(2)?.meleeHastePercent).toBe(6); expect(talent.rankEffects[1]?.effects[1]?.basePoints).toBe(7); }); it("applies the rank haste for 15 seconds and refreshes to three charges", () => { const applied = wow335ShamanFlurryApplyProc([], "shaman-1", 2, 1_000); expect(applied).toHaveLength(1); expect(applied[0]).toMatchObject({ sourceId: "shaman-1", targetId: "shaman-1", stacks: 3, appliedAt: 1_000, expiresAt: 1_000 + WOW335_SHAMAN_FLURRY_DURATION_MS, definition: { utilityTags: [WOW335_SHAMAN_FLURRY_AURA_TAG], modifiers: [{ kind: "stat", stat: "melee-haste", operation: "flat", value: 6, perStack: false }], }, }); const decremented = wow335ShamanFlurryConsumeSwingCharge(applied, "shaman-1", 2_000); expect(decremented[0]?.stacks).toBe(2); expect(wow335ShamanFlurryApplyProc(decremented, "shaman-1", 1, 3_000)[0]).toMatchObject({ stacks: 3, appliedAt: 3_000, expiresAt: 3_000 + WOW335_SHAMAN_FLURRY_DURATION_MS, definition: { modifiers: [{ value: 4 }] }, }); }); it("does not consume another Shaman's charge or an expired aura", () => { const active = wow335ShamanFlurryApplyProc([], "shaman-1", 1, 1_000); const otherOwner = wow335ShamanFlurryApplyProc(active, "shaman-2", 1, 1_000); expect(wow335ShamanFlurryConsumeSwingCharge(otherOwner, "shaman-1", 2_000)) .toEqual(expect.arrayContaining([ expect.objectContaining({ targetId: "shaman-1", stacks: 2 }), expect.objectContaining({ targetId: "shaman-2", stacks: 3 }), ])); expect(wow335ShamanFlurryConsumeSwingCharge(active, "shaman-1", 16_000)).toEqual(active); }); });