MapComparer.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * MapComparer.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 <boost/test/unit_test.hpp>
  12. #include "MapComparer.h"
  13. #define VCMI_CHECK_FIELD_EQUAL_P(field) BOOST_CHECK_EQUAL(actual->field, expected->field)
  14. #define VCMI_CHECK_FIELD_EQUAL(field) BOOST_CHECK_EQUAL(actual.field, expected.field)
  15. #define VCMI_REQUIRE_FIELD_EQUAL_P(field) BOOST_REQUIRE_EQUAL(actual->field, expected->field)
  16. #define VCMI_REQUIRE_FIELD_EQUAL(field) BOOST_REQUIRE_EQUAL(actual.field, expected.field)
  17. template <class T>
  18. void checkEqual(const T & actual, const T & expected)
  19. {
  20. BOOST_CHECK_EQUAL(actual, expected) ;
  21. }
  22. template <class Element>
  23. void checkEqual(const std::vector<Element> & actual, const std::vector<Element> & expected)
  24. {
  25. BOOST_CHECK_EQUAL(actual.size(), expected.size());
  26. for(auto actualIt = actual.begin(), expectedIt = expected.begin(); actualIt != actual.end() && expectedIt != expected.end(); actualIt++, expectedIt++)
  27. {
  28. checkEqual(*actualIt, *expectedIt);
  29. }
  30. }
  31. template <class Element>
  32. void checkEqual(const std::set<Element> & actual, const std::set<Element> & expected)
  33. {
  34. BOOST_CHECK_EQUAL(actual.size(), expected.size());
  35. for(auto elem : expected)
  36. {
  37. if(!vstd::contains(actual, elem))
  38. BOOST_ERROR("Required element not found "+boost::to_string(elem));
  39. }
  40. }
  41. void checkEqual(const PlayerInfo & actual, const PlayerInfo & expected)
  42. {
  43. VCMI_CHECK_FIELD_EQUAL(canHumanPlay);
  44. VCMI_CHECK_FIELD_EQUAL(canComputerPlay);
  45. VCMI_CHECK_FIELD_EQUAL(aiTactic);
  46. checkEqual(actual.allowedFactions, expected.allowedFactions);
  47. VCMI_CHECK_FIELD_EQUAL(isFactionRandom);
  48. VCMI_CHECK_FIELD_EQUAL(mainCustomHeroPortrait);
  49. VCMI_CHECK_FIELD_EQUAL(mainCustomHeroName);
  50. VCMI_CHECK_FIELD_EQUAL(mainCustomHeroId);
  51. //todo:heroesNames
  52. VCMI_CHECK_FIELD_EQUAL(hasMainTown);
  53. VCMI_CHECK_FIELD_EQUAL(generateHeroAtMainTown);
  54. VCMI_CHECK_FIELD_EQUAL(posOfMainTown);
  55. VCMI_CHECK_FIELD_EQUAL(team);
  56. VCMI_CHECK_FIELD_EQUAL(hasRandomHero);
  57. }
  58. void checkEqual(const EventExpression & actual, const EventExpression & expected)
  59. {
  60. //todo: checkEventExpression
  61. }
  62. void checkEqual(const TriggeredEvent & actual, const TriggeredEvent & expected)
  63. {
  64. VCMI_CHECK_FIELD_EQUAL(identifier);
  65. VCMI_CHECK_FIELD_EQUAL(description);
  66. VCMI_CHECK_FIELD_EQUAL(onFulfill);
  67. VCMI_CHECK_FIELD_EQUAL(effect.type);
  68. VCMI_CHECK_FIELD_EQUAL(effect.toOtherMessage);
  69. checkEqual(actual.trigger, expected.trigger);
  70. }
  71. void checkEqual(const TerrainTile & actual, const TerrainTile & expected)
  72. {
  73. //fatal fail here on any error
  74. VCMI_REQUIRE_FIELD_EQUAL(terType);
  75. VCMI_REQUIRE_FIELD_EQUAL(terView);
  76. VCMI_REQUIRE_FIELD_EQUAL(riverType);
  77. VCMI_REQUIRE_FIELD_EQUAL(riverDir);
  78. VCMI_REQUIRE_FIELD_EQUAL(roadType);
  79. VCMI_REQUIRE_FIELD_EQUAL(roadDir);
  80. VCMI_REQUIRE_FIELD_EQUAL(extTileFlags);
  81. }
  82. void MapComparer::compareHeader()
  83. {
  84. //map size parameters are vital for further checks
  85. VCMI_REQUIRE_FIELD_EQUAL_P(height);
  86. VCMI_REQUIRE_FIELD_EQUAL_P(width);
  87. VCMI_REQUIRE_FIELD_EQUAL_P(twoLevel);
  88. VCMI_CHECK_FIELD_EQUAL_P(name);
  89. VCMI_CHECK_FIELD_EQUAL_P(description);
  90. VCMI_CHECK_FIELD_EQUAL_P(difficulty);
  91. VCMI_CHECK_FIELD_EQUAL_P(levelLimit);
  92. VCMI_CHECK_FIELD_EQUAL_P(victoryMessage);
  93. VCMI_CHECK_FIELD_EQUAL_P(defeatMessage);
  94. VCMI_CHECK_FIELD_EQUAL_P(victoryIconIndex);
  95. VCMI_CHECK_FIELD_EQUAL_P(defeatIconIndex);
  96. checkEqual(actual->players, expected->players);
  97. //todo: allowedHeroes, placeholdedHeroes
  98. std::vector<TriggeredEvent> actualEvents = actual->triggeredEvents;
  99. std::vector<TriggeredEvent> expectedEvents = expected->triggeredEvents;
  100. auto sortByIdentifier = [](const TriggeredEvent & lhs, const TriggeredEvent & rhs) -> bool
  101. {
  102. return lhs.identifier < rhs.identifier;
  103. };
  104. boost::sort (actualEvents, sortByIdentifier);
  105. boost::sort (expectedEvents, sortByIdentifier);
  106. checkEqual(actualEvents, expectedEvents);
  107. }
  108. void MapComparer::compareOptions()
  109. {
  110. //rumors
  111. //disposedHeroes
  112. //predefinedHeroes
  113. //allowedSpell
  114. //allowedArtifact
  115. //allowedAbilities
  116. BOOST_ERROR("Not implemented compareOptions()");
  117. }
  118. void MapComparer::compareObject(const CGObjectInstance * actual, const CGObjectInstance * expected)
  119. {
  120. BOOST_CHECK_EQUAL(actual->getStringId(), expected->getStringId());
  121. BOOST_CHECK_EQUAL(typeid(actual).name(), typeid(expected).name());//todo: remove and use just comparison
  122. std::string actualFullID = boost::to_string(boost::format("%s(%d)|%s(%d)") % actual->typeName % actual->id % actual->subTypeName % actual->subID);
  123. std::string expectedFullID = boost::to_string(boost::format("%s(%d)|%s(%d)") % expected->typeName % expected->id % expected->subTypeName % expected->subID);
  124. BOOST_CHECK_EQUAL(actualFullID, expectedFullID);
  125. BOOST_CHECK_EQUAL(actual->pos, expected->pos);
  126. BOOST_CHECK_EQUAL(actual->tempOwner,expected->tempOwner);
  127. }
  128. void MapComparer::compareObjects()
  129. {
  130. BOOST_CHECK_EQUAL(actual->objects.size(), expected->objects.size());
  131. for(size_t idx = 0; idx < std::min(actual->objects.size(), expected->objects.size()); idx++)
  132. {
  133. BOOST_REQUIRE_EQUAL(idx, expected->objects[idx]->id.getNum());
  134. BOOST_CHECK_EQUAL(idx, actual->objects[idx]->id.getNum());
  135. compareObject(actual->objects[idx], expected->objects[idx]);
  136. }
  137. }
  138. void MapComparer::compareTerrain()
  139. {
  140. //assume map dimensions check passed
  141. //todo: separate check for underground
  142. for(int x = 0; x < expected->width; x++)
  143. for(int y = 0; y < expected->height; y++)
  144. {
  145. int3 coord(x,y,0);
  146. BOOST_TEST_CHECKPOINT(coord);
  147. checkEqual(actual->getTile(coord), expected->getTile(coord));
  148. }
  149. }
  150. void MapComparer::compare()
  151. {
  152. BOOST_REQUIRE_NE((void *) actual, (void *) expected); //should not point to the same object
  153. BOOST_REQUIRE_MESSAGE(actual != nullptr, "Actual map is not defined");
  154. BOOST_REQUIRE_MESSAGE(expected != nullptr, "Expected map is not defined");
  155. compareHeader();
  156. compareOptions();
  157. compareObjects();
  158. compareTerrain();
  159. }
  160. void MapComparer::operator() (const std::unique_ptr<CMap>& actual, const std::unique_ptr<CMap>& expected)
  161. {
  162. this->actual = actual.get();
  163. this->expected = expected.get();
  164. compare();
  165. }