95 lines
4.3 KiB
TypeScript
95 lines
4.3 KiB
TypeScript
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);
|
|
});
|
|
});
|