ResurceManagerTest.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * ResourceManagerTest.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 "gtest/gtest.h"
  12. #include "../AI/VCAI/VCAI.h"
  13. #include "ResourceManagerTest.h"
  14. #include "../AI/VCAI/Goals.h"
  15. #include "mock_VCAI_CGoal.h"
  16. #include "mock_VCAI.h"
  17. #include "mock_ResourceManager.h"
  18. #include "../mock/mock_CPSICallback.h"
  19. #include "../lib/CGameInfoCallback.h"
  20. using namespace Goals;
  21. using namespace ::testing;
  22. struct ResourceManagerTest : public Test//, public IResourceManager
  23. {
  24. std::unique_ptr<ResourceManagerMock> rm;
  25. NiceMock<GameCallbackMock> gcm;
  26. NiceMock<VCAIMock> aim;
  27. TSubgoal invalidGoal, gatherArmy, buildThis, buildAny, recruitHero;
  28. ResourceManagerTest()
  29. {
  30. rm = std::make_unique<NiceMock<ResourceManagerMock>>(&gcm, &aim);
  31. //note: construct new goal for modfications
  32. invalidGoal = sptr(StrictMock<InvalidGoalMock>());
  33. gatherArmy = sptr(StrictMock<GatherArmyGoalMock>());
  34. buildThis = sptr(StrictMock<BuildThis>());
  35. buildAny = sptr(StrictMock<Build>());
  36. recruitHero = sptr(StrictMock<RecruitHero>());
  37. //auto AI = CDynLibHandler::getNewAI("VCAI.dll");
  38. //SET_GLOBAL_STATE(AI);
  39. //gtest couldn't deduce default return value;
  40. ON_CALL(gcm, getTownsInfo(_))
  41. .WillByDefault(Return(std::vector < const CGTownInstance *>()));
  42. ON_CALL(gcm, getTownsInfo())
  43. .WillByDefault(Return(std::vector < const CGTownInstance *>()));
  44. ON_CALL(aim, getFlaggedObjects())
  45. .WillByDefault(Return(std::vector < const CGObjectInstance *>()));
  46. //enable if get unexpected exceptions
  47. //ON_CALL(gcm, getResourceAmount())
  48. // .WillByDefault(Return(TResources()));
  49. }
  50. };
  51. TEST_F(ResourceManagerTest, canAffordMaths)
  52. {
  53. //mocking cb calls inside canAfford()
  54. ON_CALL(gcm, getResourceAmount())
  55. .WillByDefault(Return(TResources(10, 0, 11, 0, 0, 0, 12345)));
  56. TResources buildingCost(10, 0, 10, 0, 0, 0, 5000);
  57. //EXPECT_CALL(gcm, getResourceAmount()).RetiresOnSaturation();
  58. //EXPECT_CALL(gcm, getTownsInfo(_)).RetiresOnSaturation();
  59. EXPECT_NO_THROW(rm->canAfford(buildingCost));
  60. EXPECT_TRUE(rm->canAfford(buildingCost));
  61. TResources armyCost(0, 0, 0, 0, 0, 0, 54321);
  62. EXPECT_FALSE(rm->canAfford(armyCost));
  63. rm->reserveResoures(armyCost, gatherArmy);
  64. EXPECT_FALSE(rm->canAfford(buildingCost)) << "Reserved value should be substracted from free resources";
  65. }
  66. TEST_F(ResourceManagerTest, notifyGoalImplemented)
  67. {
  68. ASSERT_FALSE(rm->hasTasksLeft());
  69. EXPECT_FALSE(rm->notifyGoalCompleted(invalidGoal));
  70. EXPECT_FALSE(rm->hasTasksLeft());
  71. TResources res(0,0,0,0,0,0,12345);;
  72. rm->reserveResoures(res, invalidGoal);
  73. ASSERT_FALSE(rm->hasTasksLeft()) << "Can't push Invalid goal";
  74. EXPECT_FALSE(rm->notifyGoalCompleted(invalidGoal));
  75. EXPECT_FALSE(rm->notifyGoalCompleted(gatherArmy)) << "Queue should be empty";
  76. rm->reserveResoures(res, gatherArmy);
  77. EXPECT_TRUE(rm->notifyGoalCompleted(gatherArmy)) << "Not implemented"; //TODO: try it with not a copy
  78. EXPECT_FALSE(rm->notifyGoalCompleted(gatherArmy)); //already completed
  79. }
  80. TEST_F(ResourceManagerTest, notifyFulfillsAll)
  81. {
  82. TResources res;
  83. ASSERT_TRUE(buildAny->fulfillsMe(buildThis)) << "Goal dependency implemented incorrectly"; //TODO: goal mock?
  84. rm->reserveResoures(res, buildAny);
  85. rm->reserveResoures(res, buildAny);
  86. rm->reserveResoures(res, buildAny);
  87. ASSERT_TRUE(rm->hasTasksLeft()); //regardless if duplicates are allowed or not
  88. rm->notifyGoalCompleted(buildThis);
  89. ASSERT_FALSE(rm->hasTasksLeft()) << "BuildThis didn't remove Build Any!";
  90. }
  91. TEST_F(ResourceManagerTest, queueOrder)
  92. {
  93. ASSERT_FALSE(rm->hasTasksLeft());
  94. TSubgoal buildLow = sptr(StrictMock<BuildThis>()),
  95. buildBit = sptr(StrictMock<BuildThis>()),
  96. buildMed = sptr(StrictMock<BuildThis>()),
  97. buildHigh = sptr(StrictMock<BuildThis>()),
  98. buildVeryHigh = sptr(StrictMock<BuildThis>()),
  99. buildExtra = sptr(StrictMock<BuildThis>()),
  100. buildNotSoExtra = sptr(StrictMock<BuildThis>());
  101. buildLow->setpriority(0).setbid(1);
  102. buildLow->setpriority(1).setbid(2);
  103. buildMed->setpriority(2).setbid(3);
  104. buildHigh->setpriority(5).setbid(4);
  105. buildVeryHigh->setpriority(10).setbid(5);
  106. TResources price(0, 0, 0, 0, 0, 0, 1000);
  107. rm->reserveResoures(price, buildLow);
  108. rm->reserveResoures(price, buildHigh);
  109. rm->reserveResoures(price, buildMed);
  110. ON_CALL(gcm, getResourceAmount())
  111. .WillByDefault(Return(TResources(0,0,0,0,0,0,4000,0))); //we can afford 4 top goals
  112. auto goal = rm->whatToDo();
  113. EXPECT_EQ(goal->goalType, Goals::BUILD_STRUCTURE);
  114. ASSERT_EQ(rm->whatToDo()->bid, 4);
  115. rm->reserveResoures(price, buildBit);
  116. rm->reserveResoures(price, buildVeryHigh);
  117. goal = rm->whatToDo();
  118. EXPECT_EQ(goal->goalType, Goals::BUILD_STRUCTURE);
  119. ASSERT_EQ(goal->bid, 5);
  120. buildExtra->setpriority(3).setbid(100);
  121. EXPECT_EQ(rm->whatToDo(price, buildExtra)->bid, 100);
  122. buildNotSoExtra->setpriority(0.7f).setbid(7);
  123. goal = rm->whatToDo(price, buildNotSoExtra);
  124. EXPECT_NE(goal->bid, 7);
  125. EXPECT_EQ(goal->goalType, Goals::COLLECT_RES) << "We can't afford this goal, need to collect resources";
  126. EXPECT_EQ(goal->resID, Res::GOLD) << "We need to collect gold";
  127. goal = rm->whatToDo();
  128. EXPECT_NE(goal->goalType, Goals::COLLECT_RES);
  129. EXPECT_EQ(goal->bid, 5) << "Should return highest-priority goal";
  130. }
  131. TEST_F(ResourceManagerTest, updateGoalImplemented)
  132. {
  133. ASSERT_FALSE(rm->hasTasksLeft());
  134. TResources res;
  135. res[Res::GOLD] = 12345;
  136. buildThis->setpriority(1);
  137. buildThis->bid = 666;
  138. EXPECT_FALSE(rm->updateGoal(buildThis)); //try update with no objectives -> fail
  139. rm->reserveResoures(res, buildThis);
  140. ASSERT_TRUE(rm->hasTasksLeft());
  141. buildThis->setpriority(4.444f);
  142. auto buildThis2 = sptr(StrictMock<BuildThis>());
  143. buildThis2->bid = 777;
  144. buildThis2->setpriority(3.33f);
  145. EXPECT_FALSE(rm->updateGoal(buildThis2)) << "Shouldn't update with wrong goal";
  146. EXPECT_TRUE(rm->updateGoal(buildThis)) << "Not implemented"; //try update with copy of reserved goal -> true
  147. EXPECT_FALSE(rm->updateGoal(invalidGoal)) << "Can't update Invalid goal";
  148. }
  149. TEST_F(ResourceManagerTest, complexGoalUpdates)
  150. {
  151. //TODO
  152. ASSERT_FALSE(rm->hasTasksLeft());
  153. }
  154. TEST_F(ResourceManagerTest, tasksLeft)
  155. {
  156. ASSERT_FALSE(rm->hasTasksLeft());
  157. }
  158. TEST_F(ResourceManagerTest, reservedResources)
  159. {
  160. //TOOO, not worth it now
  161. }
  162. TEST_F(ResourceManagerTest, freeResources)
  163. {
  164. ON_CALL(gcm, getResourceAmount()) //in case callback or gs gets crazy
  165. .WillByDefault(Return(TResources(-1, 0, -13.0f, -38763, -93764, -464, -12, -98765)));
  166. auto res = rm->freeResources();
  167. ASSERT_GE(res[Res::WOOD], 0);
  168. ASSERT_GE(res[Res::MERCURY], 0);
  169. ASSERT_GE(res[Res::ORE], 0);
  170. ASSERT_GE(res[Res::SULFUR], 0);
  171. ASSERT_GE(res[Res::CRYSTAL], 0);
  172. ASSERT_GE(res[Res::GEMS], 0);
  173. ASSERT_GE(res[Res::GOLD], 0);
  174. ASSERT_GE(res[Res::MITHRIL], 0);
  175. }
  176. TEST_F(ResourceManagerTest, freeResourcesWithManyGoals)
  177. {
  178. ON_CALL(gcm, getResourceAmount())
  179. .WillByDefault(Return(TResources(20, 10, 20, 10, 10, 10, 20000, 0)));
  180. ASSERT_EQ(rm->freeResources(), TResources(20, 10, 20, 10, 10, 10, 20000, 0));
  181. rm->reserveResoures(TResources(0, 4, 0, 0, 0, 0, 13000), gatherArmy);
  182. ASSERT_EQ(rm->freeResources(), TResources(20, 6, 20, 10, 10, 10, 7000, 0));
  183. rm->reserveResoures(TResources(5, 4, 5, 4, 4, 4, 5000), buildThis);
  184. ASSERT_EQ(rm->freeResources(), TResources(15, 2, 15, 6, 6, 6, 2000, 0));
  185. rm->reserveResoures(TResources(0, 0, 0, 0, 0, 0, 2500), recruitHero);
  186. auto res = rm->freeResources();
  187. EXPECT_EQ(res[Res::GOLD], 0) << "We should have 0 gold left";
  188. ON_CALL(gcm, getResourceAmount())
  189. .WillByDefault(Return(TResources(20, 10, 20, 10, 10, 10, 30000, 0))); //+10000 gold
  190. res = rm->freeResources();
  191. EXPECT_EQ(res[Res::GOLD], 9500) << "We should have extra savings now";
  192. }
  193. TEST_F(ResourceManagerTest, freeGold)
  194. {
  195. ON_CALL(gcm, getResourceAmount())
  196. .WillByDefault(Return(TResources(0, 0, 0, 0, 0, 0, 666)));
  197. ASSERT_EQ(rm->freeGold(), 666);
  198. ON_CALL(gcm, getResourceAmount())
  199. .WillByDefault(Return(TResources(0, 0, 0, 0, 0, 0, -3762363)));
  200. ASSERT_GE(rm->freeGold(), 0) << "We should never see negative savings";
  201. }