CBattleInfoCallbackTest.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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 & addDragon(BattleHex hex, BattleSide side)
  192. {
  193. auto & unit = addRegularMelee(hex, side);
  194. unit.addCreatureAbility(BonusType::TWO_HEX_ATTACK_BREATH);
  195. unit.makeDoubleWide();
  196. return unit;
  197. }
  198. Units getAttackedUnits(UnitFake & attacker, UnitFake & defender, BattleHex defenderHex)
  199. {
  200. startBattle();
  201. redirectUnitsToFake();
  202. return subject.getAttackedBattleUnits(
  203. &attacker, &defender,
  204. defenderHex, false,
  205. attacker.getPosition(),
  206. defender.getPosition());
  207. }
  208. };
  209. TEST_F(AttackableHexesTest, DragonRightRegular_RightHorithontalBreath)
  210. {
  211. // X A D #
  212. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  213. UnitFake & defender = addRegularMelee(36, BattleSide::DEFENDER);
  214. UnitFake & next = addRegularMelee(37, BattleSide::DEFENDER);
  215. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  216. EXPECT_TRUE(vstd::contains(attacked, &next));
  217. }
  218. TEST_F(AttackableHexesTest, DragonDragonBottomRightHead_BottomRightBreathFromHead)
  219. {
  220. // X A
  221. // D X target D
  222. // #
  223. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  224. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  225. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  226. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  227. EXPECT_TRUE(vstd::contains(attacked, &next));
  228. }
  229. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHead_VerticalDownBreathFromHead)
  230. {
  231. // X A
  232. // D X target D
  233. // #
  234. UnitFake & attacker = addDragon(35, BattleSide::ATTACKER);
  235. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  236. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  237. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  238. EXPECT_TRUE(vstd::contains(attacked, &next));
  239. }
  240. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHeadReverse_VerticalDownBreathFromHead)
  241. {
  242. // A X
  243. // X D target D
  244. // #
  245. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  246. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  247. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  248. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  249. EXPECT_TRUE(vstd::contains(attacked, &next));
  250. }
  251. TEST_F(AttackableHexesTest, DragonDragonVerticalDownBack_VerticalDownBreath)
  252. {
  253. // X A
  254. // D X target X
  255. // #
  256. UnitFake & attacker = addDragon(37, BattleSide::ATTACKER);
  257. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  258. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  259. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  260. EXPECT_TRUE(vstd::contains(attacked, &next));
  261. }
  262. TEST_F(AttackableHexesTest, DragonDragonHeadBottomRight_BottomRightBreathFromHead)
  263. {
  264. // X A
  265. // D X target D
  266. // #
  267. UnitFake & attacker = addDragon(37, BattleSide::ATTACKER);
  268. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::DEFENDER);
  269. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  270. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  271. EXPECT_TRUE(vstd::contains(attacked, &next));
  272. }
  273. TEST_F(AttackableHexesTest, DragonVerticalDownDragonBackReverse_VerticalDownBreath)
  274. {
  275. // A X
  276. // X D target X
  277. // #
  278. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  279. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  280. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  281. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  282. EXPECT_TRUE(vstd::contains(attacked, &next));
  283. }
  284. TEST_F(AttackableHexesTest, DragonRightBottomDragonHeadReverse_RightBottomBreathFromHeadHex)
  285. {
  286. // A X
  287. // X D target D
  288. UnitFake & attacker = addDragon(36, BattleSide::DEFENDER);
  289. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::ATTACKER);
  290. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), BattleSide::ATTACKER);
  291. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  292. EXPECT_TRUE(vstd::contains(attacked, &next));
  293. }
  294. TEST_F(AttackableHexesTest, DragonLeftBottomDragonBackToBack_LeftBottomBreathFromBackHex)
  295. {
  296. // X A
  297. // D X target X
  298. // #
  299. UnitFake & attacker = addDragon(8, BattleSide::ATTACKER);
  300. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT).cloneInDirection(BattleHex::LEFT), BattleSide::DEFENDER);
  301. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), BattleSide::DEFENDER);
  302. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  303. EXPECT_TRUE(vstd::contains(attacked, &next));
  304. }
  305. TEST_F(AttackableHexesTest, DefenderPositionOverride_BreathCountsHypoteticDefenderPosition)
  306. {
  307. // # N
  308. // X D target D
  309. // A X
  310. UnitFake & attacker = addDragon(35, BattleSide::DEFENDER);
  311. UnitFake & defender = addDragon(8, BattleSide::ATTACKER);
  312. UnitFake & next = addDragon(2, BattleSide::ATTACKER);
  313. startBattle();
  314. redirectUnitsToFake();
  315. auto attacked = subject.getAttackedBattleUnits(
  316. &attacker,
  317. &defender,
  318. 19,
  319. false,
  320. attacker.getPosition(),
  321. 19);
  322. EXPECT_TRUE(vstd::contains(attacked, &next));
  323. }
  324. class BattleFinishedTest : public CBattleInfoCallbackTest
  325. {
  326. public:
  327. void expectBattleNotFinished()
  328. {
  329. auto ret = subject.battleIsFinished();
  330. EXPECT_FALSE(ret);
  331. }
  332. void expectBattleDraw()
  333. {
  334. auto ret = subject.battleIsFinished();
  335. EXPECT_TRUE(ret);
  336. EXPECT_EQ(*ret, BattleSide::NONE);
  337. }
  338. void expectBattleWinner(BattleSide side)
  339. {
  340. auto ret = subject.battleIsFinished();
  341. EXPECT_TRUE(ret);
  342. EXPECT_EQ(*ret, side);
  343. }
  344. void expectBattleLooser(BattleSide side)
  345. {
  346. auto ret = subject.battleIsFinished();
  347. EXPECT_TRUE(ret);
  348. EXPECT_NE(*ret, side);
  349. }
  350. void setDefaultExpectations()
  351. {
  352. redirectUnitsToFake();
  353. unitsFake.setDefaultBonusExpectations();
  354. EXPECT_CALL(battleMock, getUnitsIf(_)).Times(1);
  355. }
  356. };
  357. TEST_F(BattleFinishedTest, DISABLED_NoBattleIsDraw)
  358. {
  359. expectBattleDraw();
  360. }
  361. TEST_F(BattleFinishedTest, EmptyBattleIsDraw)
  362. {
  363. setDefaultExpectations();
  364. startBattle();
  365. expectBattleDraw();
  366. }
  367. TEST_F(BattleFinishedTest, LastAliveUnitWins)
  368. {
  369. UnitFake & unit = unitsFake.add(BattleSide::DEFENDER);
  370. unit.makeAlive();
  371. unit.setDefaultState();
  372. setDefaultExpectations();
  373. startBattle();
  374. expectBattleWinner(BattleSide::DEFENDER);
  375. }
  376. TEST_F(BattleFinishedTest, TwoUnitsContinueFight)
  377. {
  378. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  379. unit1.makeAlive();
  380. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  381. unit2.makeAlive();
  382. setDefaultExpectations();
  383. startBattle();
  384. expectBattleNotFinished();
  385. }
  386. TEST_F(BattleFinishedTest, LastWarMachineNotWins)
  387. {
  388. UnitFake & unit = unitsFake.add(BattleSide::ATTACKER);
  389. unit.makeAlive();
  390. unit.makeWarMachine();
  391. unit.setDefaultState();
  392. setDefaultExpectations();
  393. startBattle();
  394. expectBattleLooser(BattleSide::ATTACKER);
  395. }
  396. TEST_F(BattleFinishedTest, LastWarMachineLoose)
  397. {
  398. try
  399. {
  400. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  401. unit1.makeAlive();
  402. unit1.setDefaultState();
  403. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  404. unit2.makeAlive();
  405. unit2.makeWarMachine();
  406. unit2.setDefaultState();
  407. setDefaultExpectations();
  408. startBattle();
  409. expectBattleWinner(BattleSide::ATTACKER);
  410. }
  411. catch(const std::exception & e)
  412. {
  413. logGlobal->error(e.what());
  414. }
  415. }
  416. class BattleMatchOwnerTest : public CBattleInfoCallbackTest
  417. {
  418. public:
  419. void setDefaultExpectations()
  420. {
  421. redirectUnitsToFake();
  422. unitsFake.setDefaultBonusExpectations();
  423. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::ATTACKER))).WillRepeatedly(Return(PlayerColor(0)));
  424. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::DEFENDER))).WillRepeatedly(Return(PlayerColor(1)));
  425. }
  426. };
  427. TEST_F(BattleMatchOwnerTest, normalToSelf)
  428. {
  429. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  430. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  431. setDefaultExpectations();
  432. startBattle();
  433. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  434. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  435. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  436. }
  437. TEST_F(BattleMatchOwnerTest, hypnotizedToSelf)
  438. {
  439. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  440. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  441. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  442. setDefaultExpectations();
  443. startBattle();
  444. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  445. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  446. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  447. }
  448. TEST_F(BattleMatchOwnerTest, normalToNormalAlly)
  449. {
  450. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  451. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  452. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  453. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  454. setDefaultExpectations();
  455. startBattle();
  456. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  457. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  458. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  459. }
  460. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalAlly)
  461. {
  462. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  463. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  464. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  465. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  466. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  467. setDefaultExpectations();
  468. startBattle();
  469. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  470. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  471. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  472. }
  473. TEST_F(BattleMatchOwnerTest, normalToHypnotizedAlly)
  474. {
  475. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  476. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  477. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  478. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  479. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  480. setDefaultExpectations();
  481. startBattle();
  482. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  483. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  484. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  485. }
  486. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedAlly)
  487. {
  488. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  489. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  490. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  491. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  492. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  493. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  494. setDefaultExpectations();
  495. startBattle();
  496. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  497. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  498. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  499. }
  500. TEST_F(BattleMatchOwnerTest, normalToNormalEnemy)
  501. {
  502. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  503. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  504. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  505. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  506. setDefaultExpectations();
  507. startBattle();
  508. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  509. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  510. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  511. }
  512. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalEnemy)
  513. {
  514. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  515. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  516. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  517. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  518. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  519. setDefaultExpectations();
  520. startBattle();
  521. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  522. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  523. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  524. }
  525. TEST_F(BattleMatchOwnerTest, normalToHypnotizedEnemy)
  526. {
  527. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  528. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  529. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  530. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  531. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  532. setDefaultExpectations();
  533. startBattle();
  534. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  535. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  536. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  537. }
  538. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedEnemy)
  539. {
  540. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  541. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  542. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  543. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  544. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  545. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  546. setDefaultExpectations();
  547. startBattle();
  548. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  549. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  550. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  551. }