CBattleInfoCallbackTest.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  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. void redirectBonusesToFake()
  62. {
  63. ON_CALL(*this, getAllBonuses(_, _, _, _)).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getAllBonuses));
  64. ON_CALL(*this, getTreeVersion()).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getTreeVersion));
  65. }
  66. void expectAnyBonusSystemCall()
  67. {
  68. EXPECT_CALL(*this, getAllBonuses(_, _, _, _)).Times(AtLeast(0));
  69. EXPECT_CALL(*this, getTreeVersion()).Times(AtLeast(0));
  70. }
  71. void setDefaultExpectations()
  72. {
  73. EXPECT_CALL(*this, unitSlot()).WillRepeatedly(Return(SlotID(0)));
  74. EXPECT_CALL(*this, creatureIndex()).WillRepeatedly(Return(0));
  75. }
  76. void setDefaultState()
  77. {
  78. EXPECT_CALL(*this, isClone()).WillRepeatedly(Return(false));
  79. EXPECT_CALL(*this, isCaster()).WillRepeatedly(Return(false));
  80. EXPECT_CALL(*this, acquireState()).WillRepeatedly(Return(state));
  81. }
  82. private:
  83. BonusBearerMock bonusFake;
  84. };
  85. class UnitsFake
  86. {
  87. public:
  88. std::vector<std::shared_ptr<UnitFake>> allUnits;
  89. UnitFake & add(ui8 side)
  90. {
  91. auto * unit = new UnitFake();
  92. EXPECT_CALL(*unit, unitSide()).WillRepeatedly(Return(side));
  93. unit->setDefaultExpectations();
  94. allUnits.emplace_back(unit);
  95. return *allUnits.back().get();
  96. }
  97. Units getUnitsIf(UnitFilter predicate) const
  98. {
  99. Units ret;
  100. for(auto & unit : allUnits)
  101. {
  102. if(predicate(unit.get()))
  103. ret.push_back(unit.get());
  104. }
  105. return ret;
  106. }
  107. void setDefaultBonusExpectations()
  108. {
  109. for(auto & unit : allUnits)
  110. {
  111. unit->redirectBonusesToFake();
  112. unit->expectAnyBonusSystemCall();
  113. }
  114. }
  115. };
  116. class CBattleInfoCallbackTest : public Test
  117. {
  118. public:
  119. class TestSubject : public CBattleInfoCallback
  120. {
  121. public:
  122. const IBattleInfo * battle;
  123. #if SCRIPTING_ENABLED
  124. scripting::Pool * pool;
  125. TestSubject(scripting::Pool * p)
  126. : CBattleInfoCallback(),
  127. pool(p)
  128. #else
  129. TestSubject()
  130. : CBattleInfoCallback()
  131. #endif
  132. {
  133. }
  134. const IBattleInfo * getBattle() const override
  135. {
  136. return battle;
  137. }
  138. std::optional<PlayerColor> getPlayerID() const override
  139. {
  140. return std::nullopt;
  141. }
  142. #if SCRIPTING_ENABLED
  143. scripting::Pool * getContextPool() const override
  144. {
  145. return pool;
  146. }
  147. #endif
  148. };
  149. #if SCRIPTING_ENABLED
  150. StrictMock<scripting::PoolMock> pool;
  151. #endif
  152. TestSubject subject;
  153. BattleStateMock battleMock;
  154. UnitsFake unitsFake;
  155. CBattleInfoCallbackTest()
  156. #if SCRIPTING_ENABLED
  157. : pool(),
  158. subject(&pool)
  159. #endif
  160. {
  161. }
  162. void startBattle()
  163. {
  164. subject.battle = &battleMock;
  165. }
  166. void redirectUnitsToFake()
  167. {
  168. ON_CALL(battleMock, getUnitsIf(_)).WillByDefault(Invoke(&unitsFake, &UnitsFake::getUnitsIf));
  169. }
  170. };
  171. class AttackableHexesTest : public CBattleInfoCallbackTest
  172. {
  173. public:
  174. UnitFake & addRegularMelee(BattleHex hex, uint8_t side)
  175. {
  176. auto & unit = unitsFake.add(side);
  177. unit.makeAlive();
  178. unit.setDefaultState();
  179. unit.setupPoisition(hex);
  180. unit.redirectBonusesToFake();
  181. return unit;
  182. }
  183. UnitFake & addDragon(BattleHex hex, uint8_t side)
  184. {
  185. auto & unit = addRegularMelee(hex, side);
  186. unit.addCreatureAbility(BonusType::TWO_HEX_ATTACK_BREATH);
  187. unit.makeDoubleWide();
  188. return unit;
  189. }
  190. Units getAttackedUnits(UnitFake & attacker, UnitFake & defender, BattleHex defenderHex)
  191. {
  192. startBattle();
  193. redirectUnitsToFake();
  194. return subject.getAttackedBattleUnits(
  195. &attacker, &defender,
  196. defenderHex, false,
  197. attacker.getPosition(),
  198. defender.getPosition());
  199. }
  200. };
  201. TEST_F(AttackableHexesTest, DragonRightRegular_RightHorithontalBreath)
  202. {
  203. // X A D #
  204. UnitFake & attacker = addDragon(35, 0);
  205. UnitFake & defender = addRegularMelee(36, 1);
  206. UnitFake & next = addRegularMelee(37, 1);
  207. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  208. EXPECT_TRUE(vstd::contains(attacked, &next));
  209. }
  210. TEST_F(AttackableHexesTest, DragonDragonBottomRightHead_BottomRightBreathFromHead)
  211. {
  212. // X A
  213. // D X target D
  214. // #
  215. UnitFake & attacker = addDragon(35, 0);
  216. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  217. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  218. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  219. EXPECT_TRUE(vstd::contains(attacked, &next));
  220. }
  221. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHead_VerticalDownBreathFromHead)
  222. {
  223. // X A
  224. // D X target D
  225. // #
  226. UnitFake & attacker = addDragon(35, 0);
  227. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), 1);
  228. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  229. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  230. EXPECT_TRUE(vstd::contains(attacked, &next));
  231. }
  232. TEST_F(AttackableHexesTest, DragonDragonVerticalDownHeadReverse_VerticalDownBreathFromHead)
  233. {
  234. // A X
  235. // X D target D
  236. // #
  237. UnitFake & attacker = addDragon(36, 1);
  238. UnitFake & defender = addDragon(attacker.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 0);
  239. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), 0);
  240. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  241. EXPECT_TRUE(vstd::contains(attacked, &next));
  242. }
  243. TEST_F(AttackableHexesTest, DragonDragonVerticalDownBack_VerticalDownBreath)
  244. {
  245. // X A
  246. // D X target X
  247. // #
  248. UnitFake & attacker = addDragon(37, 0);
  249. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), 1);
  250. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  251. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  252. EXPECT_TRUE(vstd::contains(attacked, &next));
  253. }
  254. TEST_F(AttackableHexesTest, DragonDragonHeadBottomRight_BottomRightBreathFromHead)
  255. {
  256. // X A
  257. // D X target D
  258. // #
  259. UnitFake & attacker = addDragon(37, 0);
  260. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT), 1);
  261. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  262. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  263. EXPECT_TRUE(vstd::contains(attacked, &next));
  264. }
  265. TEST_F(AttackableHexesTest, DragonVerticalDownDragonBackReverse_VerticalDownBreath)
  266. {
  267. // A X
  268. // X D target X
  269. // #
  270. UnitFake & attacker = addDragon(36, 1);
  271. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), 0);
  272. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), 0);
  273. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  274. EXPECT_TRUE(vstd::contains(attacked, &next));
  275. }
  276. TEST_F(AttackableHexesTest, DragonRightBottomDragonHeadReverse_RightBottomBreathFromHeadHex)
  277. {
  278. // A X
  279. // X D target D
  280. UnitFake & attacker = addDragon(36, 1);
  281. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_RIGHT), 0);
  282. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_LEFT), 0);
  283. auto attacked = getAttackedUnits(attacker, defender, defender.getPosition());
  284. EXPECT_TRUE(vstd::contains(attacked, &next));
  285. }
  286. TEST_F(AttackableHexesTest, DragonLeftBottomDragonBackToBack_LeftBottomBreathFromBackHex)
  287. {
  288. // X A
  289. // D X target X
  290. // #
  291. UnitFake & attacker = addDragon(8, 0);
  292. UnitFake & defender = addDragon(attacker.occupiedHex().cloneInDirection(BattleHex::BOTTOM_LEFT).cloneInDirection(BattleHex::LEFT), 1);
  293. UnitFake & next = addRegularMelee(defender.getPosition().cloneInDirection(BattleHex::BOTTOM_RIGHT), 1);
  294. auto attacked = getAttackedUnits(attacker, defender, defender.occupiedHex());
  295. EXPECT_TRUE(vstd::contains(attacked, &next));
  296. }
  297. TEST_F(AttackableHexesTest, DefenderPositionOverride_BreathCountsHypoteticDefenderPosition)
  298. {
  299. // # N
  300. // X D target D
  301. // A X
  302. UnitFake & attacker = addDragon(35, 1);
  303. UnitFake & defender = addDragon(8, 0);
  304. UnitFake & next = addDragon(2, 0);
  305. startBattle();
  306. redirectUnitsToFake();
  307. auto attacked = subject.getAttackedBattleUnits(
  308. &attacker,
  309. &defender,
  310. 19,
  311. false,
  312. attacker.getPosition(),
  313. 19);
  314. EXPECT_TRUE(vstd::contains(attacked, &next));
  315. }
  316. class BattleFinishedTest : public CBattleInfoCallbackTest
  317. {
  318. public:
  319. void expectBattleNotFinished()
  320. {
  321. auto ret = subject.battleIsFinished();
  322. EXPECT_FALSE(ret);
  323. }
  324. void expectBattleDraw()
  325. {
  326. auto ret = subject.battleIsFinished();
  327. EXPECT_TRUE(ret);
  328. EXPECT_EQ(*ret, 2);
  329. }
  330. void expectBattleWinner(ui8 side)
  331. {
  332. auto ret = subject.battleIsFinished();
  333. EXPECT_TRUE(ret);
  334. EXPECT_EQ(*ret, side);
  335. }
  336. void expectBattleLooser(ui8 side)
  337. {
  338. auto ret = subject.battleIsFinished();
  339. EXPECT_TRUE(ret);
  340. EXPECT_NE(*ret, (int)side);
  341. }
  342. void setDefaultExpectations()
  343. {
  344. redirectUnitsToFake();
  345. unitsFake.setDefaultBonusExpectations();
  346. EXPECT_CALL(battleMock, getUnitsIf(_)).Times(1);
  347. }
  348. };
  349. TEST_F(BattleFinishedTest, DISABLED_NoBattleIsDraw)
  350. {
  351. expectBattleDraw();
  352. }
  353. TEST_F(BattleFinishedTest, EmptyBattleIsDraw)
  354. {
  355. setDefaultExpectations();
  356. startBattle();
  357. expectBattleDraw();
  358. }
  359. TEST_F(BattleFinishedTest, LastAliveUnitWins)
  360. {
  361. UnitFake & unit = unitsFake.add(1);
  362. unit.makeAlive();
  363. unit.setDefaultState();
  364. setDefaultExpectations();
  365. startBattle();
  366. expectBattleWinner(1);
  367. }
  368. TEST_F(BattleFinishedTest, TwoUnitsContinueFight)
  369. {
  370. UnitFake & unit1 = unitsFake.add(0);
  371. unit1.makeAlive();
  372. UnitFake & unit2 = unitsFake.add(1);
  373. unit2.makeAlive();
  374. setDefaultExpectations();
  375. startBattle();
  376. expectBattleNotFinished();
  377. }
  378. TEST_F(BattleFinishedTest, LastWarMachineNotWins)
  379. {
  380. UnitFake & unit = unitsFake.add(0);
  381. unit.makeAlive();
  382. unit.makeWarMachine();
  383. unit.setDefaultState();
  384. setDefaultExpectations();
  385. startBattle();
  386. expectBattleLooser(0);
  387. }
  388. TEST_F(BattleFinishedTest, LastWarMachineLoose)
  389. {
  390. try
  391. {
  392. UnitFake & unit1 = unitsFake.add(0);
  393. unit1.makeAlive();
  394. unit1.setDefaultState();
  395. UnitFake & unit2 = unitsFake.add(1);
  396. unit2.makeAlive();
  397. unit2.makeWarMachine();
  398. unit2.setDefaultState();
  399. setDefaultExpectations();
  400. startBattle();
  401. expectBattleWinner(0);
  402. }
  403. catch(const std::exception & e)
  404. {
  405. logGlobal->error(e.what());
  406. }
  407. }
  408. class BattleMatchOwnerTest : public CBattleInfoCallbackTest
  409. {
  410. public:
  411. void setDefaultExpectations()
  412. {
  413. redirectUnitsToFake();
  414. unitsFake.setDefaultBonusExpectations();
  415. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::ATTACKER))).WillRepeatedly(Return(PlayerColor(0)));
  416. EXPECT_CALL(battleMock, getSidePlayer(Eq(BattleSide::DEFENDER))).WillRepeatedly(Return(PlayerColor(1)));
  417. }
  418. };
  419. TEST_F(BattleMatchOwnerTest, normalToSelf)
  420. {
  421. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  422. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  423. setDefaultExpectations();
  424. startBattle();
  425. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  426. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  427. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  428. }
  429. TEST_F(BattleMatchOwnerTest, hypnotizedToSelf)
  430. {
  431. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  432. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  433. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  434. setDefaultExpectations();
  435. startBattle();
  436. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, true));
  437. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit1, boost::logic::indeterminate));
  438. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit1, false));
  439. }
  440. TEST_F(BattleMatchOwnerTest, normalToNormalAlly)
  441. {
  442. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  443. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  444. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  445. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  446. setDefaultExpectations();
  447. startBattle();
  448. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  449. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  450. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  451. }
  452. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalAlly)
  453. {
  454. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  455. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  456. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  457. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  458. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  459. setDefaultExpectations();
  460. startBattle();
  461. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  462. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  463. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  464. }
  465. TEST_F(BattleMatchOwnerTest, normalToHypnotizedAlly)
  466. {
  467. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  468. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  469. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  470. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  471. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  472. setDefaultExpectations();
  473. startBattle();
  474. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  475. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  476. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  477. }
  478. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedAlly)
  479. {
  480. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  481. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  482. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  483. UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
  484. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  485. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  486. setDefaultExpectations();
  487. startBattle();
  488. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  489. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  490. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  491. }
  492. TEST_F(BattleMatchOwnerTest, normalToNormalEnemy)
  493. {
  494. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  495. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  496. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  497. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  498. setDefaultExpectations();
  499. startBattle();
  500. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  501. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  502. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  503. }
  504. TEST_F(BattleMatchOwnerTest, hypnotizedToNormalEnemy)
  505. {
  506. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  507. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  508. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  509. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  510. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  511. setDefaultExpectations();
  512. startBattle();
  513. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  514. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  515. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  516. }
  517. TEST_F(BattleMatchOwnerTest, normalToHypnotizedEnemy)
  518. {
  519. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  520. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  521. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  522. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  523. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  524. setDefaultExpectations();
  525. startBattle();
  526. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, true));
  527. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  528. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, false));
  529. }
  530. TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedEnemy)
  531. {
  532. UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
  533. EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
  534. unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  535. UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
  536. EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
  537. unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, BonusSourceID()));
  538. setDefaultExpectations();
  539. startBattle();
  540. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, true));
  541. EXPECT_TRUE(subject.battleMatchOwner(&unit1, &unit2, boost::logic::indeterminate));
  542. EXPECT_FALSE(subject.battleMatchOwner(&unit1, &unit2, false));
  543. }