AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
SpellProcArcanePotencyTest.cpp File Reference

Unit tests for Arcane Potency proc behavior. More...

#include "AuraScriptTestFramework.h"
#include "SpellMgr.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Classes

class  ArcanePotencyProcTest
 

Functions

 TEST_F (ArcanePotencyProcTest, ProcEntry_HasReqSpellmodAttribute)
 
 TEST_F (ArcanePotencyProcTest, ProcEntry_CastPhaseOnly)
 
 TEST_F (ArcanePotencyProcTest, ProcEntry_MageFamily)
 
 TEST_F (ArcanePotencyProcTest, ProcEntry_BothRanksIdentical)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_Fireball_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_Frostbolt_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_ArcaneBlast_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_ArcaneExplosion_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_FrostfireBolt_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_FireBlast_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_Scorch_Matches)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_ArcaneMissiles_DoesNotMatch)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_IceLance_DoesNotMatch)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_ArcaneBarrage_DoesNotMatch)
 
 TEST_F (ArcanePotencyProcTest, FamilyMask_NonMageSpell_DoesNotMatch)
 
 TEST_F (ArcanePotencyProcTest, Phase_TriggersOnCast)
 
 TEST_F (ArcanePotencyProcTest, Phase_DoesNotTriggerOnHit)
 
 TEST_F (ArcanePotencyProcTest, Phase_DoesNotTriggerOnFinish)
 
 TEST_F (ArcanePotencyProcTest, ReqSpellmod_AuraWithCharges_BlocksWithoutAppliedMod)
 
 TEST_F (ArcanePotencyProcTest, ReqSpellmod_AuraWithoutCharges_SkipsCheck)
 
 TEST_F (ArcanePotencyProcTest, MaskBits_CorrectBitsSet)
 
 TEST_F (ArcanePotencyProcTest, MaskBits_CorrectBitsNotSet)
 

Detailed Description

Unit tests for Arcane Potency proc behavior.

Arcane Potency (57529/57531) buffs should only be consumed by the spell that was actually affected by the crit bonus, not by the same cast that triggered them. This is achieved via PROC_ATTR_REQ_SPELLMOD (0x08) which requires the proccing aura to be in the triggering spell's m_appliedMods.

The crit aura registration in SpellDoneCritChance ensures that only spells whose crit chance was actually modified by Arcane Potency will have it in their m_appliedMods set.

References:

  • TrinityCore commit 81f16b201b
  • ChromieCraft issue #9092

Definition in file SpellProcArcanePotencyTest.cpp.

Function Documentation

◆ TEST_F() [1/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_ArcaneBarrage_DoesNotMatch   
)
211{
212 auto* spell = CreateSpellInfo(44425, SPELLFAMILY_MAGE, 0, ARCANE_BARRAGE_FLAG1);
213 auto procEntry = BuildArcanePotencyProcEntry();
214 EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
215}
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3789

References SPELLFAMILY_MAGE.

◆ TEST_F() [2/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_ArcaneBlast_Matches   
)
157{
158 auto* spell = CreateSpellInfo(30451, SPELLFAMILY_MAGE, ARCANE_BLAST_FLAG0);
159 auto procEntry = BuildArcanePotencyProcEntry();
160 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
161}

References SPELLFAMILY_MAGE.

◆ TEST_F() [3/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_ArcaneExplosion_Matches   
)
164{
165 auto* spell = CreateSpellInfo(1449, SPELLFAMILY_MAGE, ARCANE_EXPLOSION_FLAG0);
166 auto procEntry = BuildArcanePotencyProcEntry();
167 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
168}

References SPELLFAMILY_MAGE.

◆ TEST_F() [4/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_ArcaneMissiles_DoesNotMatch   
)
197{
198 auto* spell = CreateSpellInfo(5143, SPELLFAMILY_MAGE, ARCANE_MISSILES_FLAG0);
199 auto procEntry = BuildArcanePotencyProcEntry();
200 EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
201}

References SPELLFAMILY_MAGE.

◆ TEST_F() [5/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_Fireball_Matches   
)
143{
144 auto* spell = CreateSpellInfo(133, SPELLFAMILY_MAGE, FIREBALL_FLAG0);
145 auto procEntry = BuildArcanePotencyProcEntry();
146 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
147}

References SPELLFAMILY_MAGE.

◆ TEST_F() [6/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_FireBlast_Matches   
)
179{
180 auto* spell = CreateSpellInfo(2136, SPELLFAMILY_MAGE, FIRE_BLAST_FLAG0);
181 auto procEntry = BuildArcanePotencyProcEntry();
182 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
183}

References SPELLFAMILY_MAGE.

◆ TEST_F() [7/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_Frostbolt_Matches   
)
150{
151 auto* spell = CreateSpellInfo(116, SPELLFAMILY_MAGE, FROSTBOLT_FLAG0);
152 auto procEntry = BuildArcanePotencyProcEntry();
153 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
154}

References SPELLFAMILY_MAGE.

◆ TEST_F() [8/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_FrostfireBolt_Matches   
)
171{
172 auto* spell = CreateSpellInfo(44614, SPELLFAMILY_MAGE,
173 FROSTFIRE_BOLT_FLAG0, FROSTFIRE_BOLT_FLAG1);
174 auto procEntry = BuildArcanePotencyProcEntry();
175 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
176}

References SPELLFAMILY_MAGE.

◆ TEST_F() [9/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_IceLance_DoesNotMatch   
)
204{
205 auto* spell = CreateSpellInfo(30455, SPELLFAMILY_MAGE, ICE_LANCE_FLAG0);
206 auto procEntry = BuildArcanePotencyProcEntry();
207 EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
208}

References SPELLFAMILY_MAGE.

◆ TEST_F() [10/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_NonMageSpell_DoesNotMatch   
)
218{
219 // Warrior spell with matching flags should NOT match due to family check
220 auto* spell = CreateSpellInfo(6343, /*SPELLFAMILY_WARRIOR*/4, FIREBALL_FLAG0);
221 auto procEntry = BuildArcanePotencyProcEntry();
222 EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
223}

◆ TEST_F() [11/22]

TEST_F ( ArcanePotencyProcTest  ,
FamilyMask_Scorch_Matches   
)
186{
187 auto* spell = CreateSpellInfo(2948, SPELLFAMILY_MAGE, SCORCH_FLAG0);
188 auto procEntry = BuildArcanePotencyProcEntry();
189 EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
190}

References SPELLFAMILY_MAGE.

◆ TEST_F() [12/22]

TEST_F ( ArcanePotencyProcTest  ,
MaskBits_CorrectBitsNotSet   
)
339{
340 // Bit 11: Arcane Missiles - should NOT be set
341 EXPECT_FALSE(AP_FAMILY_MASK0 & 0x00000800);
342 // Bit 17: Ice Lance - should NOT be set
343 EXPECT_FALSE(AP_FAMILY_MASK0 & 0x00020000);
344 // Mask1 bit 15: Arcane Barrage - should NOT be set
345 EXPECT_FALSE(AP_FAMILY_MASK1 & 0x00008000);
346}

◆ TEST_F() [13/22]

TEST_F ( ArcanePotencyProcTest  ,
MaskBits_CorrectBitsSet   
)
317{
318 // Verify the exact bits in our SpellFamilyMask0
319 // Bit 0: Fireball
320 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00000001);
321 // Bit 2: Frostfire Bolt
322 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00000004);
323 // Bit 4: Fire Blast
324 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00000010);
325 // Bit 5: Frostbolt
326 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00000020);
327 // Bit 12: Arcane Explosion
328 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00001000);
329 // Bit 22: Scorch
330 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x00400000);
331 // Bit 29: Arcane Blast
332 EXPECT_TRUE(AP_FAMILY_MASK0 & 0x20000000);
333
334 // Mask1: Bit 12 (Frostfire Bolt secondary)
335 EXPECT_TRUE(AP_FAMILY_MASK1 & 0x00001000);
336}

◆ TEST_F() [14/22]

TEST_F ( ArcanePotencyProcTest  ,
Phase_DoesNotTriggerOnFinish   
)
260{
261 auto procEntry = SpellProcEntryBuilder()
265 .Build();
266
267 auto scenario = ProcScenarioBuilder()
269 .OnFinish();
270 EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, scenario);
271}
#define EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, scenario)
Definition AuraScriptTestFramework.h:478
@ PROC_ATTR_REQ_SPELLMOD
Definition SpellMgr.h:279
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:248
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:134
Helper class for testing specific proc scenarios.
Definition AuraScriptTestFramework.h:252
ProcScenarioBuilder & OnFinish()
Definition AuraScriptTestFramework.h:415
ProcScenarioBuilder & OnSpellDamage()
Definition AuraScriptTestFramework.h:282
Builder class for creating SpellProcEntry test instances.
Definition ProcEventInfoHelper.h:141
SpellProcEntry Build() const
Definition ProcEventInfoHelper.h:226
SpellProcEntryBuilder & WithAttributesMask(uint32 attributesMask)
Definition ProcEventInfoHelper.h:190
SpellProcEntryBuilder & WithProcFlags(uint32 procFlags)
Definition ProcEventInfoHelper.h:166
SpellProcEntryBuilder & WithSpellPhaseMask(uint32 spellPhaseMask)
Definition ProcEventInfoHelper.h:178

References SpellProcEntryBuilder::Build(), EXPECT_PROC_DOES_NOT_TRIGGER, ProcScenarioBuilder::OnFinish(), ProcScenarioBuilder::OnSpellDamage(), PROC_ATTR_REQ_SPELLMOD, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_PHASE_CAST, SpellProcEntryBuilder::WithAttributesMask(), SpellProcEntryBuilder::WithProcFlags(), and SpellProcEntryBuilder::WithSpellPhaseMask().

◆ TEST_F() [15/22]

◆ TEST_F() [16/22]

TEST_F ( ArcanePotencyProcTest  ,
Phase_TriggersOnCast   
)
230{
231 // Test phase filtering in isolation (no family filter)
232 auto procEntry = SpellProcEntryBuilder()
236 .Build();
237
238 auto scenario = ProcScenarioBuilder()
240 .OnCast();
241 EXPECT_PROC_TRIGGERS(procEntry, scenario);
242}
#define EXPECT_PROC_TRIGGERS(procEntry, scenario)
Definition AuraScriptTestFramework.h:472
ProcScenarioBuilder & OnCast()
Definition AuraScriptTestFramework.h:403

References SpellProcEntryBuilder::Build(), EXPECT_PROC_TRIGGERS, ProcScenarioBuilder::OnCast(), ProcScenarioBuilder::OnSpellDamage(), PROC_ATTR_REQ_SPELLMOD, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_PHASE_CAST, SpellProcEntryBuilder::WithAttributesMask(), SpellProcEntryBuilder::WithProcFlags(), and SpellProcEntryBuilder::WithSpellPhaseMask().

◆ TEST_F() [17/22]

TEST_F ( ArcanePotencyProcTest  ,
ProcEntry_BothRanksIdentical   
)
127{
128 // Both ranks should use the same proc configuration
129 auto r1 = BuildArcanePotencyProcEntry();
130 auto r2 = BuildArcanePotencyProcEntry();
131
132 EXPECT_EQ(r1.SpellFamilyName, r2.SpellFamilyName);
133 EXPECT_TRUE(r1.SpellFamilyMask == r2.SpellFamilyMask);
134 EXPECT_EQ(r1.SpellPhaseMask, r2.SpellPhaseMask);
135 EXPECT_EQ(r1.AttributesMask, r2.AttributesMask);
136}

◆ TEST_F() [18/22]

TEST_F ( ArcanePotencyProcTest  ,
ProcEntry_CastPhaseOnly   
)
114{
115 auto procEntry = BuildArcanePotencyProcEntry();
116 EXPECT_EQ(procEntry.SpellPhaseMask, PROC_SPELL_PHASE_CAST)
117 << "Arcane Potency should only proc on CAST phase";
118}

References PROC_SPELL_PHASE_CAST.

◆ TEST_F() [19/22]

TEST_F ( ArcanePotencyProcTest  ,
ProcEntry_HasReqSpellmodAttribute   
)
106{
107 auto procEntry = BuildArcanePotencyProcEntry();
108 EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
109 << "Arcane Potency must have PROC_ATTR_REQ_SPELLMOD to prevent "
110 "same-cast consumption";
111}

References PROC_ATTR_REQ_SPELLMOD.

◆ TEST_F() [20/22]

TEST_F ( ArcanePotencyProcTest  ,
ProcEntry_MageFamily   
)
121{
122 auto procEntry = BuildArcanePotencyProcEntry();
123 EXPECT_EQ(procEntry.SpellFamilyName, SPELLFAMILY_MAGE);
124}

References SPELLFAMILY_MAGE.

◆ TEST_F() [21/22]

TEST_F ( ArcanePotencyProcTest  ,
ReqSpellmod_AuraWithCharges_BlocksWithoutAppliedMod   
)
278{
279 // When PROC_ATTR_REQ_SPELLMOD is set and aura uses charges,
280 // GetProcEffectMask should return 0 if aura is not in m_appliedMods.
281 // We test the prerequisite: that the proc entry is configured correctly
282 // so the charge-gating code path in GetProcEffectMask is reachable.
283 auto procEntry = BuildArcanePotencyProcEntry();
284
285 auto aura = AuraStubBuilder()
286 .WithId(ARCANE_POTENCY_R1)
287 .WithCharges(1)
288 .Build();
289
290 // The aura should be using charges (required for REQ_SPELLMOD gating)
291 EXPECT_TRUE(aura->IsUsingCharges());
292 EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD);
293}
Builder for creating AuraStub instances with fluent API.
Definition AuraStub.h:290
AuraStubBuilder & WithCharges(uint8_t charges)
Definition AuraStub.h:306
std::unique_ptr< AuraStub > Build()
Definition AuraStub.h:353
AuraStubBuilder & WithId(uint32_t id)
Definition AuraStub.h:294

References AuraStubBuilder::Build(), PROC_ATTR_REQ_SPELLMOD, AuraStubBuilder::WithCharges(), and AuraStubBuilder::WithId().

◆ TEST_F() [22/22]

TEST_F ( ArcanePotencyProcTest  ,
ReqSpellmod_AuraWithoutCharges_SkipsCheck   
)
296{
297 // If aura has no charges, PROC_ATTR_REQ_SPELLMOD check is skipped
298 // (no charges to consume = no need for spellmod gating)
299 auto procEntry = BuildArcanePotencyProcEntry();
300
301 auto aura = AuraStubBuilder()
302 .WithId(ARCANE_POTENCY_R1)
303 .WithCharges(0)
304 .Build();
305
306 EXPECT_FALSE(aura->IsUsingCharges());
307 // Even though PROC_ATTR_REQ_SPELLMOD is set, the condition
308 // (IsUsingCharges() || USE_STACKS_FOR_CHARGES) would be false
309 // so the spellmod check would be skipped
310}

References AuraStubBuilder::Build(), AuraStubBuilder::WithCharges(), and AuraStubBuilder::WithId().