SummonTest.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * SummonTest.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "EffectFixture.h"
  12. #include <vstd/RNG.h>
  13. #include "../../../lib/CCreatureHandler.h"
  14. #include "../../../lib/json/JsonNode.h"
  15. namespace test
  16. {
  17. using namespace ::spells;
  18. using namespace ::spells::effects;
  19. using namespace ::testing;
  20. static const CreatureID creature1(CreatureID::AIR_ELEMENTAL);
  21. static const CreatureID creature2(CreatureID::FIRE_ELEMENTAL);
  22. class SummonTest : public TestWithParam<::testing::tuple<CreatureID, bool, bool>>, public EffectFixture
  23. {
  24. public:
  25. CreatureID toSummon;
  26. CreatureID otherSummoned;
  27. bool exclusive;
  28. bool summonSameUnit;
  29. const battle::Unit * otherSummonedUnit;
  30. SummonTest()
  31. : EffectFixture("core:summon"),
  32. otherSummonedUnit(nullptr)
  33. {
  34. }
  35. void addOtherSummoned(bool expectAlive)
  36. {
  37. auto & unit = unitsFake.add(BattleSide::ATTACKER);
  38. EXPECT_CALL(unit, unitOwner()).WillRepeatedly(Return(PlayerColor(5)));
  39. EXPECT_CALL(unit, isClone()).WillRepeatedly(Return(false));
  40. EXPECT_CALL(unit, creatureId()).WillRepeatedly(Return(otherSummoned));
  41. EXPECT_CALL(unit, isValidTarget(Eq(false))).WillRepeatedly(Return(true));
  42. EXPECT_CALL(unit, getPosition()).WillRepeatedly(Return(BattleHex(5,5)));
  43. EXPECT_CALL(unit, doubleWide()).WillRepeatedly(Return(false));
  44. EXPECT_CALL(unit, unitSide()).Times(AnyNumber());
  45. EXPECT_CALL(unit, unitSlot()).WillRepeatedly(Return(SlotID::SUMMONED_SLOT_PLACEHOLDER));
  46. if(expectAlive)
  47. EXPECT_CALL(unit, alive()).WillRepeatedly(Return(true));
  48. else
  49. EXPECT_CALL(unit, alive()).Times(0);
  50. otherSummonedUnit = &unit;
  51. }
  52. protected:
  53. void SetUp() override
  54. {
  55. EffectFixture::setUp();
  56. otherSummoned = ::testing::get<0>(GetParam());
  57. exclusive = ::testing::get<1>(GetParam());
  58. summonSameUnit = ::testing::get<2>(GetParam());
  59. toSummon = creature1;
  60. JsonNode options;
  61. options["id"].String() = "airElemental";
  62. options["exclusive"].Bool() = exclusive;
  63. options["summonSameUnit"].Bool() = summonSameUnit;
  64. EffectFixture::setupEffect(options);
  65. }
  66. };
  67. TEST_P(SummonTest, DISABLED_Applicable)
  68. {
  69. const bool expectedApplicable = !exclusive || otherSummoned == CreatureID() || otherSummoned == toSummon;
  70. if(otherSummoned != CreatureID())
  71. addOtherSummoned(false);
  72. if(otherSummoned != CreatureID() && !expectedApplicable)
  73. EXPECT_CALL(problemMock, add(_));
  74. if(exclusive)
  75. EXPECT_CALL(*battleFake, getUnitsIf(_)).Times(AtLeast(1));
  76. else
  77. EXPECT_CALL(*battleFake, getUnitsIf(_)).Times(0);
  78. EXPECT_CALL(mechanicsMock, getCasterColor()).WillRepeatedly(Return(PlayerColor(5)));
  79. EXPECT_EQ(expectedApplicable, subject->applicable(problemMock, &mechanicsMock));
  80. }
  81. TEST_P(SummonTest, DISABLED_Transform)
  82. {
  83. if(otherSummoned != CreatureID())
  84. addOtherSummoned(true);
  85. battleFake->setupEmptyBattlefield();
  86. EXPECT_CALL(*battleFake, getUnitsIf(_)).Times(AtLeast(1));
  87. EXPECT_CALL(mechanicsMock, getCasterColor()).WillRepeatedly(Return(PlayerColor(5)));
  88. EffectTarget transformed = subject->transformTarget(&mechanicsMock, Target(), Target());
  89. EffectTarget expected;
  90. if(otherSummoned == toSummon && summonSameUnit)
  91. {
  92. expected.emplace_back(otherSummonedUnit);
  93. }
  94. else
  95. {
  96. expected.emplace_back(BattleHex(1));
  97. }
  98. EXPECT_THAT(transformed, ContainerEq(expected));
  99. }
  100. INSTANTIATE_TEST_SUITE_P
  101. (
  102. ByConfig,
  103. SummonTest,
  104. Combine
  105. (
  106. Values(CreatureID(), creature1, creature2),
  107. Values(false, true),
  108. Values(false, true)
  109. )
  110. );
  111. class SummonApplyTest : public TestWithParam<::testing::tuple<bool, bool>>, public EffectFixture
  112. {
  113. public:
  114. const CreatureID toSummon = CreatureID::AIR_ELEMENTAL;
  115. bool permanent = false;
  116. bool summonByHealth = false;
  117. const uint32_t unitId = 42;
  118. const int32_t unitAmount = 123;
  119. const int32_t unitHealth = 479;
  120. const int64_t unitTotalHealth = unitAmount * unitHealth;
  121. const BattleHex unitPosition = BattleHex(5,5);
  122. std::shared_ptr<::battle::UnitInfo> unitAddInfo;
  123. std::shared_ptr<battle::UnitFake> acquired;
  124. StrictMock<CreatureMock> toSummonType;
  125. SummonApplyTest()
  126. : EffectFixture("core:summon")
  127. {
  128. }
  129. void setDefaultExpectations()
  130. {
  131. EXPECT_CALL(mechanicsMock, creatures()).Times(AnyNumber());
  132. EXPECT_CALL(creatureServiceMock, getById(Eq(toSummon))).WillRepeatedly(Return(&toSummonType));
  133. EXPECT_CALL(toSummonType, getMaxHealth()).WillRepeatedly(Return(unitHealth));
  134. expectAmountCalculation();
  135. }
  136. void expectAmountCalculation()
  137. {
  138. InSequence local;
  139. EXPECT_CALL(mechanicsMock, getEffectPower()).WillOnce(Return(38));
  140. EXPECT_CALL(mechanicsMock, calculateRawEffectValue(Eq(0), Eq(38))).WillOnce(Return(567));
  141. if(summonByHealth)
  142. {
  143. EXPECT_CALL(mechanicsMock, applySpecificSpellBonus(Eq(567))).WillOnce(Return(unitTotalHealth));
  144. }
  145. else
  146. {
  147. EXPECT_CALL(mechanicsMock, applySpecificSpellBonus(Eq(567))).WillOnce(Return(unitAmount));
  148. }
  149. }
  150. void onUnitAdded(uint32_t id, const JsonNode & data)
  151. {
  152. unitAddInfo->load(id, data);
  153. }
  154. protected:
  155. void SetUp() override
  156. {
  157. EffectFixture::setUp();
  158. permanent = ::testing::get<0>(GetParam());
  159. summonByHealth = ::testing::get<1>(GetParam());
  160. JsonNode options;
  161. options["id"].String() = "airElemental";
  162. options["permanent"].Bool() = permanent;
  163. options["summonByHealth"].Bool() = summonByHealth;
  164. EffectFixture::setupEffect(options);
  165. unitAddInfo = std::make_shared<::battle::UnitInfo>();
  166. }
  167. void TearDown() override
  168. {
  169. acquired.reset();
  170. unitAddInfo.reset();
  171. }
  172. };
  173. TEST_P(SummonApplyTest, DISABLED_SpawnsNewUnit)
  174. {
  175. setDefaultExpectations();
  176. EXPECT_CALL(*battleFake, nextUnitId()).WillOnce(Return(unitId));
  177. EXPECT_CALL(*battleFake, addUnit(Eq(unitId), _)).WillOnce(Invoke(this, &SummonApplyTest::onUnitAdded));
  178. EXPECT_CALL(serverMock, apply(Matcher<BattleUnitsChanged &>(_))).Times(1);
  179. EffectTarget target;
  180. target.emplace_back(unitPosition);
  181. subject->apply(&serverMock, &mechanicsMock, target);
  182. EXPECT_EQ(unitAddInfo->count, unitAmount);
  183. EXPECT_EQ(unitAddInfo->id, unitId);
  184. EXPECT_EQ(unitAddInfo->position, unitPosition);
  185. EXPECT_EQ(unitAddInfo->side, mechanicsMock.casterSide);
  186. EXPECT_EQ(unitAddInfo->summoned, !permanent);
  187. EXPECT_EQ(unitAddInfo->type, toSummon);
  188. }
  189. TEST_P(SummonApplyTest, DISABLED_UpdatesOldUnit)
  190. {
  191. setDefaultExpectations();
  192. acquired = std::make_shared<battle::UnitFake>();
  193. acquired->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, BonusSourceID()));
  194. acquired->redirectBonusesToFake();
  195. acquired->expectAnyBonusSystemCall();
  196. auto & unit = unitsFake.add(BattleSide::ATTACKER);
  197. unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, BonusSourceID()));
  198. {
  199. EXPECT_CALL(unit, acquire()).WillOnce(Return(acquired));
  200. EXPECT_CALL(*acquired, heal(Eq(unitTotalHealth), Eq(EHealLevel::OVERHEAL), Eq(permanent ? EHealPower::PERMANENT : EHealPower::ONE_BATTLE)));
  201. EXPECT_CALL(*acquired, save(_));
  202. EXPECT_CALL(*battleFake, setUnitState(Eq(unitId), _, _));
  203. }
  204. EXPECT_CALL(unit, unitId()).WillOnce(Return(unitId));
  205. EXPECT_CALL(serverMock, apply(Matcher<BattleUnitsChanged &>(_))).Times(1);
  206. unitsFake.setDefaultBonusExpectations();
  207. EffectTarget target;
  208. target.emplace_back(&unit, BattleHex());
  209. subject->apply(&serverMock, &mechanicsMock, target);
  210. }
  211. INSTANTIATE_TEST_SUITE_P
  212. (
  213. ByConfig,
  214. SummonApplyTest,
  215. Combine
  216. (
  217. Values(false, true),
  218. Values(false, true)
  219. )
  220. );
  221. }