CUnitStateTest.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * CUnitStateTest.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 "mock/mock_BonusBearer.h"
  12. #include "mock/mock_UnitInfo.h"
  13. #include "mock/mock_UnitEnvironment.h"
  14. #include "../../lib/bonuses/BonusSubtypes.h"
  15. #include "../../lib/battle/CUnitState.h"
  16. #include "../../lib/CCreatureHandler.h"
  17. namespace test
  18. {
  19. using namespace ::testing;
  20. static const int32_t DEFAULT_HP = 123;
  21. static const int32_t DEFAULT_AMOUNT = 100;
  22. static const int32_t DEFAULT_SPEED = 10;
  23. static const BattleHex DEFAULT_POSITION = BattleHex(5, 5);
  24. static const int DEFAULT_ATTACK = 58;
  25. static const int DEFAULT_DEFENCE = 63;
  26. class UnitStateTest : public Test
  27. {
  28. public:
  29. UnitInfoMock infoMock;
  30. UnitEnvironmentMock envMock;
  31. BonusBearerMock bonusMock;
  32. const CCreature * pikeman;
  33. battle::CUnitStateDetached subject;
  34. bool hasAmmoCart;
  35. UnitStateTest()
  36. :infoMock(),
  37. envMock(),
  38. bonusMock(),
  39. subject(&infoMock, &bonusMock),
  40. hasAmmoCart(false)
  41. {
  42. pikeman = CreatureID(0).toCreature();
  43. }
  44. void setDefaultExpectations()
  45. {
  46. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, 0));
  47. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, 0, TBonusSubtype(PrimarySkill::ATTACK)));
  48. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, 0, TBonusSubtype(PrimarySkill::DEFENSE)));
  49. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, 0));
  50. EXPECT_CALL(infoMock, unitBaseAmount()).WillRepeatedly(Return(DEFAULT_AMOUNT));
  51. EXPECT_CALL(infoMock, unitType()).WillRepeatedly(Return(pikeman));
  52. EXPECT_CALL(envMock, unitHasAmmoCart(_)).WillRepeatedly(Return(hasAmmoCart));
  53. }
  54. void makeShooter(int32_t ammo)
  55. {
  56. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOOTER, BonusSource::CREATURE_ABILITY, 1, 0));
  57. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOTS, BonusSource::CREATURE_ABILITY, ammo, 0));
  58. }
  59. void initUnit()
  60. {
  61. subject.localInit(&envMock);
  62. subject.position = DEFAULT_POSITION;
  63. }
  64. };
  65. TEST_F(UnitStateTest, initialRegular)
  66. {
  67. setDefaultExpectations();
  68. initUnit();
  69. EXPECT_TRUE(subject.alive());
  70. EXPECT_TRUE(subject.ableToRetaliate());
  71. EXPECT_FALSE(subject.isGhost());
  72. EXPECT_FALSE(subject.isDead());
  73. EXPECT_FALSE(subject.isTurret());
  74. EXPECT_TRUE(subject.isValidTarget(true));
  75. EXPECT_TRUE(subject.isValidTarget(false));
  76. EXPECT_FALSE(subject.isClone());
  77. EXPECT_FALSE(subject.hasClone());
  78. EXPECT_FALSE(subject.canCast());
  79. EXPECT_FALSE(subject.isCaster());
  80. EXPECT_FALSE(subject.canShoot());
  81. EXPECT_FALSE(subject.isShooter());
  82. EXPECT_EQ(subject.getCount(), DEFAULT_AMOUNT);
  83. EXPECT_EQ(subject.getFirstHPleft(), DEFAULT_HP);
  84. EXPECT_EQ(subject.getKilled(), 0);
  85. EXPECT_EQ(subject.getAvailableHealth(), DEFAULT_HP * DEFAULT_AMOUNT);
  86. EXPECT_EQ(subject.getTotalHealth(), subject.getAvailableHealth());
  87. EXPECT_EQ(subject.getPosition(), DEFAULT_POSITION);
  88. EXPECT_EQ(subject.getInitiative(), DEFAULT_SPEED);
  89. EXPECT_EQ(subject.getInitiative(123456), DEFAULT_SPEED);
  90. EXPECT_TRUE(subject.canMove());
  91. EXPECT_TRUE(subject.canMove(123456));
  92. EXPECT_FALSE(subject.defended());
  93. EXPECT_FALSE(subject.defended(123456));
  94. EXPECT_FALSE(subject.moved());
  95. EXPECT_FALSE(subject.moved(123456));
  96. EXPECT_TRUE(subject.willMove());
  97. EXPECT_TRUE(subject.willMove(123456));
  98. EXPECT_FALSE(subject.waited());
  99. EXPECT_FALSE(subject.waited(123456));
  100. EXPECT_EQ(subject.getTotalAttacks(true), 1);
  101. EXPECT_EQ(subject.getTotalAttacks(false), 1);
  102. }
  103. TEST_F(UnitStateTest, canShoot)
  104. {
  105. setDefaultExpectations();
  106. makeShooter(1);
  107. initUnit();
  108. EXPECT_FALSE(subject.canCast());
  109. EXPECT_FALSE(subject.isCaster());
  110. EXPECT_TRUE(subject.canShoot());
  111. EXPECT_TRUE(subject.isShooter());
  112. subject.afterAttack(true, false);
  113. EXPECT_FALSE(subject.canShoot());
  114. EXPECT_TRUE(subject.isShooter());
  115. }
  116. TEST_F(UnitStateTest, canShootWithAmmoCart)
  117. {
  118. hasAmmoCart = true;
  119. setDefaultExpectations();
  120. makeShooter(1);
  121. initUnit();
  122. EXPECT_FALSE(subject.canCast());
  123. EXPECT_FALSE(subject.isCaster());
  124. EXPECT_TRUE(subject.canShoot());
  125. EXPECT_TRUE(subject.isShooter());
  126. subject.afterAttack(true, false);
  127. EXPECT_TRUE(subject.canShoot());
  128. EXPECT_TRUE(subject.isShooter());
  129. }
  130. TEST_F(UnitStateTest, getAttack)
  131. {
  132. setDefaultExpectations();
  133. EXPECT_EQ(subject.getAttack(false), DEFAULT_ATTACK);
  134. EXPECT_EQ(subject.getAttack(true), DEFAULT_ATTACK);
  135. }
  136. TEST_F(UnitStateTest, getDefense)
  137. {
  138. setDefaultExpectations();
  139. EXPECT_EQ(subject.getDefense(false), DEFAULT_DEFENCE);
  140. EXPECT_EQ(subject.getDefense(true), DEFAULT_DEFENCE);
  141. }
  142. TEST_F(UnitStateTest, attackWithFrenzy)
  143. {
  144. setDefaultExpectations();
  145. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, 0));
  146. int expectedAttack = static_cast<int>(DEFAULT_ATTACK + 0.5 * DEFAULT_DEFENCE);
  147. EXPECT_EQ(subject.getAttack(false), expectedAttack);
  148. EXPECT_EQ(subject.getAttack(true), expectedAttack);
  149. }
  150. TEST_F(UnitStateTest, defenceWithFrenzy)
  151. {
  152. setDefaultExpectations();
  153. bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, 0));
  154. int expectedDefence = 0;
  155. EXPECT_EQ(subject.getDefense(false), expectedDefence);
  156. EXPECT_EQ(subject.getDefense(true), expectedDefence);
  157. }
  158. TEST_F(UnitStateTest, additionalAttack)
  159. {
  160. setDefaultExpectations();
  161. {
  162. auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
  163. bonusMock.addNewBonus(bonus);
  164. }
  165. EXPECT_EQ(subject.getTotalAttacks(false), 42);
  166. EXPECT_EQ(subject.getTotalAttacks(true), 42);
  167. }
  168. TEST_F(UnitStateTest, additionalMeleeAttack)
  169. {
  170. setDefaultExpectations();
  171. {
  172. auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
  173. bonus->effectRange = BonusLimitEffect::ONLY_MELEE_FIGHT;
  174. bonusMock.addNewBonus(bonus);
  175. }
  176. EXPECT_EQ(subject.getTotalAttacks(false), 42);
  177. EXPECT_EQ(subject.getTotalAttacks(true), 1);
  178. }
  179. TEST_F(UnitStateTest, additionalRangedAttack)
  180. {
  181. setDefaultExpectations();
  182. {
  183. auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
  184. bonus->effectRange = BonusLimitEffect::ONLY_DISTANCE_FIGHT;
  185. bonusMock.addNewBonus(bonus);
  186. }
  187. EXPECT_EQ(subject.getTotalAttacks(false), 1);
  188. EXPECT_EQ(subject.getTotalAttacks(true), 42);
  189. }
  190. TEST_F(UnitStateTest, getMinDamage)
  191. {
  192. setDefaultExpectations();
  193. {
  194. auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
  195. bonusMock.addNewBonus(bonus);
  196. bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMin);
  197. bonusMock.addNewBonus(bonus);
  198. }
  199. EXPECT_EQ(subject.getMinDamage(false), 10);
  200. EXPECT_EQ(subject.getMinDamage(true), 10);
  201. }
  202. TEST_F(UnitStateTest, getMaxDamage)
  203. {
  204. setDefaultExpectations();
  205. {
  206. auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
  207. bonusMock.addNewBonus(bonus);
  208. bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMax);
  209. bonusMock.addNewBonus(bonus);
  210. }
  211. EXPECT_EQ(subject.getMaxDamage(false), 10);
  212. EXPECT_EQ(subject.getMaxDamage(true), 10);
  213. }
  214. }