CBattleInfoCallbackTest.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /*
  2. * CBattleInfoCallbackTest.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 "../../lib/battle/CBattleInfoCallback.h"
  12. #include "../../lib/battle/CUnitState.h"
  13. #include <vstd/RNG.h>
  14. #include "mock/mock_BonusBearer.h"
  15. #include "mock/mock_battle_IBattleState.h"
  16. #include "mock/mock_battle_Unit.h"
  17. #if SCRIPTING_ENABLED
  18. #include "mock/mock_scripting_Pool.h"
  19. #endif
  20. using namespace battle;
  21. using namespace testing;
  22. class UnitFake : public UnitMock
  23. {
  24. private:
  25. std::shared_ptr<CUnitState> state;
  26. public:
  27. UnitFake()
  28. {
  29. state.reset(new CUnitStateDetached(this, this));
  30. }
  31. void addNewBonus(const std::shared_ptr<Bonus> & b)
  32. {
  33. bonusFake.addNewBonus(b);
  34. }
  35. void addCreatureAbility(BonusType bonusType)
  36. {
  37. addNewBonus(
  38. std::make_shared<Bonus>(
  39. BonusDuration::PERMANENT,
  40. bonusType,
  41. BonusSource::CREATURE_ABILITY,
  42. 0,
  43. CreatureID(0)));
  44. }
  45. void makeAlive()
  46. {
  47. EXPECT_CALL(*this, alive()).WillRepeatedly(Return(true));
  48. }
  49. void setupPoisition(BattleHex pos)
  50. {
  51. EXPECT_CALL(*this, getPosition()).WillRepeatedly(Return(pos));
  52. }
  53. void makeDoubleWide()
  54. {
  55. EXPECT_CALL(*this, doubleWide()).WillRepeatedly(Return(true));
  56. }
  57. void makeWarMachine()
  58. {
  59. addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SIEGE_WEAPON, BonusSource::CREATURE_ABILITY, 1, BonusSourceID()));
  60. }
  61. bool isHypnotized() const override
  62. {
  63. return hasBonusOfType(BonusType::HYPNOTIZED);
  64. }
  65. bool isInvincible() const override
  66. {
  67. return hasBonusOfType(BonusType::INVINCIBLE);
  68. }
  69. void redirectBonusesToFake()
  70. {
  71. ON_CALL(*this, getAllBonuses(_, _, _)).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getAllBonuses));
  72. ON_CALL(*this, getTreeVersion()).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getTreeVersion));
  73. }
  74. void expectAnyBonusSystemCall()
  75. {
  76. EXPECT_CALL(*this, getAllBonuses(_, _, _)).Times(AtLeast(0));
  77. EXPECT_CALL(*this, getTreeVersion()).Times(AtLeast(0));
  78. }
  79. void setDefaultExpectations()
  80. {
  81. EXPECT_CALL(*this, unitSlot()).WillRepeatedly(Return(SlotID(0)));
  82. EXPECT_CALL(*this, creatureIndex()).WillRepeatedly(Return(0));
  83. }
  84. void setDefaultState()
  85. {
  86. EXPECT_CALL(*this, isClone()).WillRepeatedly(Return(false));
  87. EXPECT_CALL(*this, isCaster()).WillRepeatedly(Return(false));
  88. EXPECT_CALL(*this, acquireState()).WillRepeatedly(Return(state));
  89. }
  90. private:
  91. BonusBearerMock bonusFake;
  92. };
  93. class UnitsFake
  94. {
  95. public:
  96. std::vector<std::shared_ptr<UnitFake>> allUnits;
  97. UnitFake & add(BattleSide side)
  98. {
  99. auto * unit = new UnitFake();
  100. EXPECT_CALL(*unit, unitSide()).WillRepeatedly(Return(side));
  101. unit->setDefaultExpectations();
  102. allUnits.emplace_back(unit);
  103. return *allUnits.back().get();
  104. }
  105. Units getUnitsIf(UnitFilter predicate) const
  106. {
  107. Units ret;
  108. for(auto & unit : allUnits)
  109. {
  110. if(predicate(unit.get()))
  111. ret.push_back(unit.get());
  112. }
  113. return ret;
  114. }
  115. void setDefaultBonusExpectations()
  116. {
  117. for(auto & unit : allUnits)
  118. {
  119. unit->redirectBonusesToFake();
  120. unit->expectAnyBonusSystemCall();
  121. }
  122. }
  123. };
  124. class CBattleInfoCallbackTest : public Test
  125. {
  126. public:
  127. class TestSubject : public CBattleInfoCallback
  128. {
  129. public:
  130. const IBattleInfo * battle;
  131. #if SCRIPTING_ENABLED
  132. scripting::Pool * pool;
  133. TestSubject(scripting::Pool * p)
  134. : CBattleInfoCallback(),
  135. pool(p)
  136. #else
  137. TestSubject()
  138. : CBattleInfoCallback()
  139. #endif
  140. {
  141. }
  142. const IBattleInfo * getBattle() const override
  143. {
  144. return battle;
  145. }
  146. std::optional<PlayerColor> getPlayerID() const override
  147. {
  148. return std::nullopt;
  149. }
  150. #if SCRIPTING_ENABLED
  151. scripting::Pool * getContextPool() const override
  152. {
  153. return pool;
  154. }
  155. #endif
  156. };
  157. #if SCRIPTING_ENABLED
  158. StrictMock<scripting::PoolMock> pool;
  159. #endif
  160. TestSubject subject;
  161. BattleStateMock battleMock;
  162. UnitsFake unitsFake;
  163. CBattleInfoCallbackTest()
  164. #if SCRIPTING_ENABLED
  165. : pool(),
  166. subject(&pool)
  167. #endif
  168. {
  169. }
  170. void startBattle()
  171. {
  172. subject.battle = &battleMock;
  173. }
  174. void redirectUnitsToFake()
  175. {
  176. ON_CALL(battleMock, getUnitsIf(_)).WillByDefault(Invoke(&unitsFake, &UnitsFake::getUnitsIf));
  177. }
  178. };
  179. class AttackableHexesTest : public CBattleInfoCallbackTest
  180. {
  181. public:
  182. UnitFake & addRegularMelee(BattleHex hex, BattleSide side)
  183. {
  184. auto & unit = unitsFake.add(side);
  185. unit.makeAlive();
  186. unit.setDefaultState();
  187. unit.setupPoisition(hex);
  188. unit.redirectBonusesToFake();
  189. return unit;
  190. }
  191. UnitFake & addCerberi(BattleHex hex, BattleSide side)
  192. {
  193. auto & unit = addRegularMelee(hex, side);
  194. unit.addCreatureAbility(BonusType::THREE_HEADED_ATTACK);
  195. unit.makeDoubleWide();
  196. return unit;
  197. }
  198. UnitFake & addDragon(BattleHex hex, BattleSide side)
  199. {
  200. auto & unit = addRegularMelee(hex, side);
  201. unit.addCreatureAbility(BonusType::TWO_HEX_ATTACK_BREATH);
  202. unit.makeDoubleWide();
  203. return unit;
  204. }
  205. Units getAttackedUnits(UnitFake & attacker, UnitFake & defender, BattleHex defenderHex)
  206. {
  207. startBattle();
  208. redirectUnitsToFake();
  209. return subject.getAttackedBattleUnits(
  210. &attacker, &defender,
  211. defenderHex, false,
  212. attacker.getPosition(),
  213. defender.getPosition());
  214. }
  215. };
  216. //// CERBERI 3-HEADED ATTACKS
  217. TEST_F(AttackableHexesTest, CerberiAttackerRight)
  218. {
  219. // #
  220. // X A D
  221. // #
  222. UnitFake & attacker = addCerberi(35, BattleSide::ATTACKER);
  223. UnitFake & defender = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::RIGHT), BattleSide::DEFENDER);
  224. UnitFake & right = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  225. UnitFake & left = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::TOP_RIGHT), BattleSide::DEFENDER);
  226. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  227. EXPECT_TRUE(vstd::contains(attacked, &defender));
  228. EXPECT_TRUE(vstd::contains(attacked, &right));
  229. EXPECT_TRUE(vstd::contains(attacked, &left));
  230. }
  231. TEST_F(AttackableHexesTest, CerberiAttackerTopRight)
  232. {
  233. // # D
  234. // X A #
  235. //
  236. UnitFake & attacker = addCerberi(35, BattleSide::ATTACKER);
  237. UnitFake & defender = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::TOP_RIGHT), BattleSide::DEFENDER);
  238. UnitFake & right = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::RIGHT), BattleSide::DEFENDER);
  239. UnitFake & left = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::TOP_LEFT), BattleSide::DEFENDER);
  240. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  241. EXPECT_TRUE(vstd::contains(attacked, &right));
  242. EXPECT_TRUE(vstd::contains(attacked, &left));
  243. }
  244. TEST_F(AttackableHexesTest, CerberiAttackerTopMiddle)
  245. {
  246. // # D #
  247. // X A
  248. //
  249. UnitFake & attacker = addCerberi(35, BattleSide::ATTACKER);
  250. UnitFake & defender = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::TOP_LEFT), BattleSide::DEFENDER);
  251. UnitFake & right = addRegularMelee(attacker.getPosition().cloneInDirection(BattleHex::TOP_RIGHT), BattleSide::DEFENDER);
  252. UnitFake & left = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::TOP_LEFT), BattleSide::DEFENDER);
  253. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  254. EXPECT_TRUE(vstd::contains(attacked, &right));
  255. EXPECT_TRUE(vstd::contains(attacked, &left));
  256. }
  257. TEST_F(AttackableHexesTest, CerberiAttackerTopLeft)
  258. {
  259. // D #
  260. // # X A
  261. //
  262. UnitFake & attacker = addCerberi(40, BattleSide::ATTACKER);
  263. UnitFake & defender = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::TOP_LEFT), BattleSide::DEFENDER);
  264. UnitFake & right = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::TOP_RIGHT), BattleSide::DEFENDER);
  265. UnitFake & left = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::LEFT), BattleSide::DEFENDER);
  266. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  267. EXPECT_TRUE(vstd::contains(attacked, &right));
  268. EXPECT_TRUE(vstd::contains(attacked, &left));
  269. }
  270. TEST_F(AttackableHexesTest, CerberiAttackerLeft)
  271. {
  272. // #
  273. // D X A
  274. // #
  275. UnitFake & attacker = addCerberi(40, BattleSide::ATTACKER);
  276. UnitFake & defender = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::LEFT), BattleSide::DEFENDER);
  277. UnitFake & right = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::TOP_LEFT), BattleSide::DEFENDER);
  278. UnitFake & left = addRegularMelee(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  279. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  280. EXPECT_TRUE(vstd::contains(attacked, &right));
  281. EXPECT_TRUE(vstd::contains(attacked, &left));
  282. }
  283. //// DRAGON BREATH AS ATTACKER
  284. TEST_F(AttackableHexesTest, DragonRightRegular_RightHorithontalBreath)
  285. {
  286. // X A D #
  287. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  288. UnitFake & defender = addRegularMelee(36, BattleSide::DEFENDER);
  289. UnitFake & next = addRegularMelee(37, BattleSide::DEFENDER);
  290. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  291. EXPECT_TRUE(vstd::contains(attacked, &defender));
  292. EXPECT_TRUE(vstd::contains(attacked, &next));
  293. }
  294. TEST_F(AttackableHexesTest, DragonDragonBottomRightHead_BottomRightBreathFromHead)
  295. {
  296. // X A
  297. // D X target D
  298. // #
  299. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  300. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  301. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  302. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  303. EXPECT_TRUE(vstd::contains(attacked, &next));
  304. }
  305. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHead_VerticalDownBreathFromHead)
  306. {
  307. // X A
  308. // D X target D
  309. // #
  310. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  311. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  312. UnitFake & next = addRegularMelee(defender.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  313. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  314. EXPECT_TRUE(vstd::contains(attacked, &next));
  315. }
  316. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHead_VerticalRightBreathFromHead)
  317. {
  318. // X A
  319. // D X target X
  320. // #
  321. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  322. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  323. UnitFake & next = addRegularMelee(defender.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  324. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  325. EXPECT_TRUE(vstd::contains(attacked, &next));
  326. }
  327. TEST_F(AttackableHexesTest, DragonDragonVerticalDownBack_VerticalDownBreath)
  328. {
  329. // X A
  330. // D X target X
  331. // #
  332. UnitFake & attacker = addDragon(37, BattleSide::ATTACKER);
  333. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  334. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  335. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  336. EXPECT_TRUE(vstd::contains(attacked, &next));
  337. }
  338. TEST_F(AttackableHexesTest, DragonDragonHeadBottomRight_BottomRightBreathFromHead)
  339. {
  340. // X A
  341. // D X target D
  342. // #
  343. UnitFake & attacker = addDragon(37, BattleSide::ATTACKER);
  344. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  345. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  346. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  347. EXPECT_TRUE(vstd::contains(attacked, &next));
  348. }
  349. TEST_F(AttackableHexesTest, DragonLeftBottomDragonBackToBack_LeftBottomBreathFromBackHex)
  350. {
  351. // X A
  352. // D X target X
  353. // #
  354. UnitFake & attacker = addDragon(8, BattleSide::ATTACKER);
  355. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT).cloneInDirection(BattleHex::LEFT), BattleSide::DEFENDER);
  356. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  357. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  358. EXPECT_TRUE(vstd::contains(attacked, &next));
  359. }
  360. //// DRAGON BREATH AS DEFENDER
  361. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHeadReverse_VerticalDownBreathFromHead)
  362. {
  363. // A X
  364. // X D target D
  365. // #
  366. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  367. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  368. UnitFake & next = addRegularMelee(defender.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  369. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  370. EXPECT_TRUE(vstd::contains(attacked, &next));
  371. }
  372. TEST_F(AttackableHexesTest, DragonVerticalDownDragonBackReverse_VerticalDownBreath)
  373. {
  374. // A X
  375. // X D target X
  376. // #
  377. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  378. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  379. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  380. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  381. EXPECT_TRUE(vstd::contains(attacked, &next));
  382. }
  383. TEST_F(AttackableHexesTest, DragonRightBottomDragonHeadReverse_RightBottomBreathFromHeadHex)
  384. {
  385. // A X
  386. // X D target D
  387. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  388. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  389. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  390. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  391. EXPECT_TRUE(vstd::contains(attacked, &next));
  392. }
  393. TEST_F(AttackableHexesTest, DefenderPositionOverride_BreathCountsHypoteticDefenderPosition)
  394. {
  395. // # N
  396. // X D target D
  397. // A X
  398. UnitFake & attacker = addDragon(35, BattleSide::DEFENDER);
  399. UnitFake & defender = addDragon(8, BattleSide::ATTACKER);
  400. UnitFake & next = addDragon(1, BattleSide::ATTACKER);
  401. startBattle();
  402. redirectUnitsToFake();
  403. auto attacked = subject.getAttackedBattleUnits(
  404. &attacker,
  405. &defender,
  406. 19,
  407. false,
  408. attacker.getPosition(),
  409. 19);
  410. EXPECT_TRUE(vstd::contains(attacked, &next));
  411. }
  412. class BattleFinishedTest : public CBattleInfoCallbackTest
  413. {
  414. public:
  415. void expectBattleNotFinished()
  416. {
  417. auto ret = subject.battleIsFinished();
  418. EXPECT_FALSE(ret);
  419. }
  420. void expectBattleDraw()
  421. {
  422. auto ret = subject.battleIsFinished();
  423. EXPECT_TRUE(ret);
  424. EXPECT_EQ(*ret, BattleSide::NONE);
  425. }
  426. void expectBattleWinner(BattleSide side)
  427. {
  428. auto ret = subject.battleIsFinished();
  429. EXPECT_TRUE(ret);
  430. EXPECT_EQ(*ret, side);
  431. }
  432. void expectBattleLooser(BattleSide side)
  433. {
  434. auto ret = subject.battleIsFinished();
  435. EXPECT_TRUE(ret);
  436. EXPECT_NE(*ret, side);
  437. }
  438. void setDefaultExpectations()
  439. {
  440. redirectUnitsToFake();
  441. unitsFake.setDefaultBonusExpectations();
  442. EXPECT_CALL(battleMock, getUnitsIf(_)).Times(1);
  443. }
  444. };
  445. TEST_F(BattleFinishedTest, DISABLED_NoBattleIsDraw)
  446. {
  447. expectBattleDraw();
  448. }
  449. TEST_F(BattleFinishedTest, EmptyBattleIsDraw)
  450. {
  451. setDefaultExpectations();
  452. startBattle();
  453. expectBattleDraw();
  454. }
  455. TEST_F(BattleFinishedTest, LastAliveUnitWins)
  456. {
  457. UnitFake & unit = unitsFake.add(BattleSide::DEFENDER);
  458. unit.makeAlive();
  459. unit.setDefaultState();
  460. setDefaultExpectations();
  461. startBattle();
  462. expectBattleWinner(BattleSide::DEFENDER);
  463. }
  464. TEST_F(BattleFinishedTest, TwoUnitsContinueFight)
  465. {
  466. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  467. unit1.makeAlive();
  468. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  469. unit2.makeAlive();
  470. setDefaultExpectations();
  471. startBattle();
  472. expectBattleNotFinished();
  473. }
  474. TEST_F(BattleFinishedTest, LastWarMachineNotWins)
  475. {
  476. UnitFake & unit = unitsFake.add(BattleSide::ATTACKER);
  477. unit.makeAlive();
  478. unit.makeWarMachine();
  479. unit.setDefaultState();
  480. setDefaultExpectations();
  481. startBattle();
  482. expectBattleLooser(BattleSide::ATTACKER);
  483. }
  484. TEST_F(BattleFinishedTest, LastWarMachineLoose)
  485. {
  486. try
  487. {
  488. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  489. unit1.makeAlive();
  490. unit1.setDefaultState();
  491. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  492. unit2.makeAlive();
  493. unit2.makeWarMachine();
  494. unit2.setDefaultState();
  495. setDefaultExpectations();
  496. startBattle();
  497. expectBattleWinner(BattleSide::ATTACKER);
  498. }
  499. catch(const std::exception & e)
  500. {
  501. logGlobal->error(e.what());
  502. }
  503. }
  504. class BattleMatchOwnerTest : public CBattleInfoCallbackTest
  505. {
  506. public:
  507. void setDefaultExpectations()
  508. {
  509. redirectUnitsToFake();
  510. unitsFake.setDefaultBonusExpectations();
  511. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::ATTACKER))).WillRepeatedly(Return(PlayerColor(0)));
  512. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::DEFENDER))).WillRepeatedly(Return(PlayerColor(1)));
  513. }
  514. };
  515. TEST_F(BattleMatchOwnerTest, normalToSelf)
  516. {
  517. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  518. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  519. setDefaultExpectations();
  520. startBattle();
  521. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  522. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  523. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  524. }
  525. TEST_F(BattleMatchOwnerTest, hypnotizedToSelf)
  526. {
  527. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  528. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  529. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  530. setDefaultExpectations();
  531. startBattle();
  532. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  533. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  534. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  535. }
  536. TEST_F(BattleMatchOwnerTest, normalToNormalAlly)
  537. {
  538. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  539. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  540. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  541. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  542. setDefaultExpectations();
  543. startBattle();
  544. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  545. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  546. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  547. }
  548. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalAlly)
  549. {
  550. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  551. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  552. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  553. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  554. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  555. setDefaultExpectations();
  556. startBattle();
  557. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  558. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  559. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  560. }
  561. TEST_F(BattleMatchOwnerTest, normalToHypnotizedAlly)
  562. {
  563. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  564. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  565. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  566. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  567. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  568. setDefaultExpectations();
  569. startBattle();
  570. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  571. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  572. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  573. }
  574. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedAlly)
  575. {
  576. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  577. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  578. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  579. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  580. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  581. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  582. setDefaultExpectations();
  583. startBattle();
  584. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  585. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  586. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  587. }
  588. TEST_F(BattleMatchOwnerTest, normalToNormalEnemy)
  589. {
  590. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  591. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  592. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  593. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  594. setDefaultExpectations();
  595. startBattle();
  596. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  597. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  598. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  599. }
  600. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalEnemy)
  601. {
  602. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  603. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  604. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  605. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  606. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  607. setDefaultExpectations();
  608. startBattle();
  609. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  610. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  611. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  612. }
  613. TEST_F(BattleMatchOwnerTest, normalToHypnotizedEnemy)
  614. {
  615. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  616. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  617. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  618. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  619. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  620. setDefaultExpectations();
  621. startBattle();
  622. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  623. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  624. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  625. }
  626. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedEnemy)
  627. {
  628. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  629. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  630. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  631. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  632. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  633. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  634. setDefaultExpectations();
  635. startBattle();
  636. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  637. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  638. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  639. }