CUnitStateTest.cpp 7.7 KB

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