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   
)
210{
211 auto* spell = CreateSpellInfo(44425, SPELLFAMILY_MAGE, 0, ARCANE_BARRAGE_FLAG1);
212 auto procEntry = BuildArcanePotencyProcEntry();
213 EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, spell));
214}
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3787

References SPELLFAMILY_MAGE.

◆ TEST_F() [2/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [3/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [4/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [5/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [6/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [7/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [8/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [9/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [10/22]

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

◆ TEST_F() [11/22]

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

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   
)
259{
260 auto procEntry = SpellProcEntryBuilder()
264 .Build();
265
266 auto scenario = ProcScenarioBuilder()
268 .OnFinish();
269 EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, scenario);
270}
#define EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, scenario)
Definition AuraScriptTestFramework.h:471
@ 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:245
ProcScenarioBuilder & OnFinish()
Definition AuraScriptTestFramework.h:408
ProcScenarioBuilder & OnSpellDamage()
Definition AuraScriptTestFramework.h:275
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   
)
229{
230 // Test phase filtering in isolation (no family filter)
231 auto procEntry = SpellProcEntryBuilder()
235 .Build();
236
237 auto scenario = ProcScenarioBuilder()
239 .OnCast();
240 EXPECT_PROC_TRIGGERS(procEntry, scenario);
241}
#define EXPECT_PROC_TRIGGERS(procEntry, scenario)
Definition AuraScriptTestFramework.h:465
ProcScenarioBuilder & OnCast()
Definition AuraScriptTestFramework.h:396

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   
)
126{
127 // Both ranks should use the same proc configuration
128 auto r1 = BuildArcanePotencyProcEntry();
129 auto r2 = BuildArcanePotencyProcEntry();
130
131 EXPECT_EQ(r1.SpellFamilyName, r2.SpellFamilyName);
132 EXPECT_TRUE(r1.SpellFamilyMask == r2.SpellFamilyMask);
133 EXPECT_EQ(r1.SpellPhaseMask, r2.SpellPhaseMask);
134 EXPECT_EQ(r1.AttributesMask, r2.AttributesMask);
135}

◆ TEST_F() [18/22]

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

References PROC_SPELL_PHASE_CAST.

◆ TEST_F() [19/22]

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

References PROC_ATTR_REQ_SPELLMOD.

◆ TEST_F() [20/22]

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

References SPELLFAMILY_MAGE.

◆ TEST_F() [21/22]

TEST_F ( ArcanePotencyProcTest  ,
ReqSpellmod_AuraWithCharges_BlocksWithoutAppliedMod   
)
277{
278 // When PROC_ATTR_REQ_SPELLMOD is set and aura uses charges,
279 // GetProcEffectMask should return 0 if aura is not in m_appliedMods.
280 // We test the prerequisite: that the proc entry is configured correctly
281 // so the charge-gating code path in GetProcEffectMask is reachable.
282 auto procEntry = BuildArcanePotencyProcEntry();
283
284 auto aura = AuraStubBuilder()
285 .WithId(ARCANE_POTENCY_R1)
286 .WithCharges(1)
287 .Build();
288
289 // The aura should be using charges (required for REQ_SPELLMOD gating)
290 EXPECT_TRUE(aura->IsUsingCharges());
291 EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD);
292}
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   
)
295{
296 // If aura has no charges, PROC_ATTR_REQ_SPELLMOD check is skipped
297 // (no charges to consume = no need for spellmod gating)
298 auto procEntry = BuildArcanePotencyProcEntry();
299
300 auto aura = AuraStubBuilder()
301 .WithId(ARCANE_POTENCY_R1)
302 .WithCharges(0)
303 .Build();
304
305 EXPECT_FALSE(aura->IsUsingCharges());
306 EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD);
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(), PROC_ATTR_REQ_SPELLMOD, AuraStubBuilder::WithCharges(), and AuraStubBuilder::WithId().