瀏覽代碼

Merge branch 'improvingTheBattle' into develop

AlexVinS 8 年之前
父節點
當前提交
303a3b670c

+ 3 - 0
.gitmodules

@@ -0,0 +1,3 @@
+[submodule "test/googletest"]
+	path = test/googletest
+	url = https://github.com/google/googletest

+ 3 - 4
.travis.yml

@@ -17,15 +17,14 @@ matrix:
   - os: linux
     compiler: clang
     env: VCMI_PLATFORM='linux' REAL_CC=clang-3.6 REAL_CXX=clang++-3.6 PACKAGE=clang-3.6
-      SUPPORT=libstdc++-4.8-dev VCMI_CMAKE_FLAGS='-DENABLE_TEST=0'
+      SUPPORT=libstdc++-4.8-dev
   - os: linux
     compiler: clang
     env: VCMI_PLATFORM='linux' REAL_CC=clang-3.4 REAL_CXX=clang++-3.4 PACKAGE=clang-3.4
-      SUPPORT=libstdc++-4.8-dev VCMI_CMAKE_FLAGS='-DENABLE_TEST=0'
+      SUPPORT=libstdc++-4.8-dev
   - os: linux
     compiler: gcc
     env: VCMI_PLATFORM='linux' REAL_CC=gcc-4.8   REAL_CXX=g++-4.8     PACKAGE=g++-4.8   SUPPORT=
-      VCMI_CMAKE_FLAGS='-DENABLE_TEST=0'
   - os: linux
     env: VCMI_PLATFORM='mxe' MXE_TARGET=i686-w64-mingw32.shared VCMI_CMAKE_FLAGS='-DENABLE_TEST=0'
     sudo: required
@@ -40,7 +39,7 @@ addons:
     notification_email: [email protected]
     build_command_prepend: cov-configure --compiler clang-3.6 --comptype clangcc &&
       cov-configure --comptype clangcxx --compiler clang++-3.6 && cmake -G Ninja ..
-      -DCMAKE_BUILD_TYPE=DEBUG -DENABLE_LAUNCHER=0 -DENABLE_TEST=0
+      -DCMAKE_BUILD_TYPE=DEBUG -DENABLE_LAUNCHER=0
     build_command: ninja -j 3
     branch_pattern: coverity_scan
 

+ 0 - 125
test/Battlefield.cpp

@@ -1,125 +0,0 @@
-/*
- * Battlefield.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
-#include "StdInc.h"
-#include <boost/test/unit_test.hpp>
-#include "../lib/battle/BattleHex.h"
-BOOST_AUTO_TEST_SUITE(BattlefieldHex_Suite)
-
-BOOST_AUTO_TEST_CASE(getNeighbouringTiles)
-{
-	BattleHex mainHex;
-	std::vector<BattleHex> neighbouringTiles;
-	mainHex.setXY(16,0);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==1);
-	mainHex.setXY(0,0);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==2);
-	mainHex.setXY(15,2);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==3);
-	mainHex.setXY(2,0);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==4);
-	mainHex.setXY(1,2);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==5);
-	mainHex.setXY(8,5);
-	neighbouringTiles = mainHex.neighbouringTiles();
-	BOOST_TEST(neighbouringTiles.size()==6);
-
-	BOOST_REQUIRE(neighbouringTiles.size()==6 && mainHex==93);
-	BOOST_TEST(neighbouringTiles.at(0)==75);
-	BOOST_TEST(neighbouringTiles.at(1)==76);
-	BOOST_TEST(neighbouringTiles.at(2)==94);
-	BOOST_TEST(neighbouringTiles.at(3)==110);
-	BOOST_TEST(neighbouringTiles.at(4)==109);
-	BOOST_TEST(neighbouringTiles.at(5)==92);
-}
-
-BOOST_AUTO_TEST_CASE(getDistance)
-{
-	BattleHex firstHex(0,0), secondHex(16,0);
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==16);
-	firstHex=0, secondHex=170;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==10);
-	firstHex=16, secondHex=181;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==10);
-	firstHex=186, secondHex=70;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==17);
-	firstHex=166, secondHex=39;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==11);
-	firstHex=25, secondHex=103;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==9);
-	firstHex=18, secondHex=71;
-	BOOST_TEST((int)firstHex.getDistance(firstHex,secondHex)==4);
-}
-
-BOOST_AUTO_TEST_CASE(mutualPositions)
-{
-	BattleHex firstHex(0,0), secondHex(16,0);
-	firstHex=86, secondHex=68;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==0);
-	secondHex=69;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==1);
-	secondHex=87;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==2);
-	secondHex=103;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==3);
-	secondHex=102;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==4);
-	secondHex=85;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==5);
-	secondHex=46;
-	BOOST_TEST((int)firstHex.mutualPosition(firstHex,secondHex)==-1);
-}
-
-BOOST_AUTO_TEST_CASE(getClosestTile)
-{
-	BattleHex mainHex(0);
-	std::set<BattleHex> possibilities;
-	possibilities.insert(3);
-	possibilities.insert(170);
-	possibilities.insert(100);
-	possibilities.insert(119);
-	possibilities.insert(186);
-
-	BOOST_TEST(mainHex.getClosestTile(0,mainHex,possibilities)==3);
-	mainHex = 139;
-	BOOST_TEST(mainHex.getClosestTile(1,mainHex,possibilities)==119);
-	mainHex = 16;
-	BOOST_TEST(mainHex.getClosestTile(1,mainHex,possibilities)==100);
-	mainHex = 166;
-	BOOST_TEST(mainHex.getClosestTile(0,mainHex,possibilities)==186);
-	mainHex = 76;
-	BOOST_TEST(mainHex.getClosestTile(1,mainHex,possibilities)==3);
-	BOOST_TEST(mainHex.getClosestTile(0,mainHex,possibilities)==100);
-}
-
-BOOST_AUTO_TEST_CASE(moveEDir)
-{
-	BattleHex mainHex(20);
-	mainHex.moveInDirection(BattleHex::EDir::BOTTOM_RIGHT);
-	BOOST_TEST(mainHex==37);
-	mainHex.moveInDirection(BattleHex::EDir::RIGHT);
-	BOOST_TEST(mainHex==38);
-	mainHex.moveInDirection(BattleHex::EDir::TOP_RIGHT);
-	BOOST_TEST(mainHex==22);
-	mainHex.moveInDirection(BattleHex::EDir::TOP_LEFT);
-	BOOST_TEST(mainHex==4);
-	mainHex.moveInDirection(BattleHex::EDir::LEFT);
-	BOOST_TEST(mainHex==3);
-	mainHex.moveInDirection(BattleHex::EDir::BOTTOM_LEFT);
-	BOOST_TEST(mainHex==20);
-	mainHex.moveInDirection(BattleHex::EDir::NONE);
-	BOOST_TEST(mainHex==20);
-}
-
-BOOST_AUTO_TEST_SUITE_END()

+ 35 - 17
test/CMakeLists.txt

@@ -1,30 +1,48 @@
 cmake_minimum_required(VERSION 2.8.7)
+
 project(test)
+
 enable_testing()
+
+set(googleTest_Dir ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
+if (EXISTS ${googleTest_Dir})
+    SET(GTestSrc ${googleTest_Dir}/googletest)
+    SET(GMockSrc ${googleTest_Dir}/googlemock)
+else ()
+    message( FATAL_ERROR "No googletest src dir found!")
+endif ()
+include_directories(${GTestSrc} ${GTestSrc}/include ${GMockSrc} ${GMockSrc}/include)
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/test)
 include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
 
 set(test_SRCS
-		StdInc.cpp
-
-		Battlefield.cpp
-		CMapEditManagerTest.cpp
-		CMapFormatTest.cpp
-		CMemoryBufferTest.cpp
-		CVcmiTestConfig.cpp
-		MapComparer.cpp
-                battle/CHealthTest.cpp
+ 		StdInc.cpp
+ 		main.cpp
+ 		CMemoryBufferTest.cpp
+ 		CVcmiTestConfig.cpp
+ 
+ 		battle/BattleHexTest.cpp
+ 		battle/CHealthTest.cpp
+
+ 		map/CMapEditManagerTest.cpp
+ 		map/CMapFormatTest.cpp
+ 		map/MapComparer.cpp
 )
 
 set(test_HEADERS
-		StdInc.h
+ 		StdInc.h
+ 
+ 		CVcmiTestConfig.h
+ 		map/MapComparer.h
+)
 
-		CVcmiTestConfig.h
-		MapComparer.h
+set(mock_HEADERS
+    mock/mock_UnitHealthInfo.h
 )
+add_subdirectory(googletest)
 
-add_executable(vcmitest ${test_SRCS} ${test_HEADERS})
-target_link_libraries(vcmitest vcmi ${Boost_LIBRARIES} ${RT_LIB} ${DL_LIB})
+add_executable(vcmitest ${test_SRCS} ${test_HEADERS} ${mock_HEADERS} ${GTestSrc}/src/gtest-all.cc ${GMockSrc}/src/gmock-all.cc)
+target_link_libraries(vcmitest vcmi ${RT_LIB} ${DL_LIB})
 add_test(vcmitest vcmitest)
 
 vcmi_set_output_dir(vcmitest "")
@@ -44,7 +62,7 @@ set(vcmitest_FILES
 )
 
 foreach(file ${vcmitest_FILES})
-                add_custom_command(TARGET vcmitestFiles POST_BUILD
-                                COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${file}" ${CMAKE_CURRENT_BINARY_DIR}
-        )
+		add_custom_command(TARGET vcmitestFiles POST_BUILD
+				COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${file}" ${CMAKE_CURRENT_BINARY_DIR}
+	)
 endforeach()

+ 14 - 20
test/CMemoryBufferTest.cpp

@@ -7,46 +7,40 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
+
 #include "StdInc.h"
-#include <boost/test/unit_test.hpp>
 #include "../lib/filesystem/CMemoryBuffer.h"
 
-struct CMemoryBufferFixture
+struct CMemoryBufferTest : testing::Test
 {
 	CMemoryBuffer subject;
 };
 
-BOOST_AUTO_TEST_SUITE(CMemoryBuffer_Suite)
 
-BOOST_FIXTURE_TEST_CASE(empty, CMemoryBufferFixture)
+TEST_F(CMemoryBufferTest, empty)
 {
-	BOOST_REQUIRE_EQUAL(0, subject.tell());
-	BOOST_REQUIRE_EQUAL(0, subject.getSize());
-
+	EXPECT_EQ(subject.tell(), 0);
+	EXPECT_EQ(subject.getSize(), 0);
 	si32 dummy = 1337;
-
 	auto ret = subject.read((ui8 *)&dummy, sizeof(si32));
-
-	BOOST_CHECK_EQUAL(0, ret);
-	BOOST_CHECK_EQUAL(1337, dummy);
-	BOOST_CHECK_EQUAL(0, subject.tell());
+	EXPECT_EQ(ret, 0);
+	EXPECT_EQ(dummy, 1337);
+	EXPECT_EQ(subject.tell(), 0);
 }
 
-BOOST_FIXTURE_TEST_CASE(write, CMemoryBufferFixture)
+TEST_F(CMemoryBufferTest, write)
 {
 	const si32 initial = 1337;
 
 	subject.write((const ui8 *)&initial, sizeof(si32));
 
-	BOOST_CHECK_EQUAL(4, subject.tell());
+	EXPECT_EQ(subject.tell(), 4);
 	subject.seek(0);
-	BOOST_CHECK_EQUAL(0, subject.tell());
+	EXPECT_EQ(subject.tell(), 0);
 
 	si32 current = 0;
 	auto ret = subject.read((ui8 *)&current, sizeof(si32));
-	BOOST_CHECK_EQUAL(sizeof(si32), ret);
-	BOOST_CHECK_EQUAL(initial, current);
-	BOOST_CHECK_EQUAL(4, subject.tell());
+	EXPECT_EQ(ret, sizeof(si32));
+	EXPECT_EQ(current, initial);
+	EXPECT_EQ(subject.tell(), 4);
 }
-
-BOOST_AUTO_TEST_SUITE_END()

+ 1 - 4
test/CVcmiTestConfig.cpp

@@ -24,13 +24,9 @@
 CVcmiTestConfig::CVcmiTestConfig()
 {
 	console = new CConsoleHandler();
-	CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() / "VCMI_Test_log.txt", console);
-	logConfig.configureDefault();
 	preinitDLL(console);
 	settings.init();
-	logConfig.configure();
 	loadDLLClasses();
-	logGlobal->info("Initialized global test setup.");
 
 	/* TEST_DATA_DIR may be wrong, if yes below test don't run,
 	find your test data folder in your build and change TEST_DATA_DIR for it*/
@@ -47,3 +43,4 @@ CVcmiTestConfig::~CVcmiTestConfig()
 {
 	std::cout << "Ending global test tear-down." << std::endl;
 }
+

+ 9 - 7
test/StdInc.cpp

@@ -1,10 +1,12 @@
+/*
+ * StdInc.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
 // Creates the precompiled header
 #include "StdInc.h"
 
-#ifndef _MSC_VER
-	// Should be defined only once, before #include of unit test header
-	#define BOOST_TEST_MODULE VcmiTest
-	#include <boost/test/unit_test.hpp>
-	#include "CVcmiTestConfig.h"
-	BOOST_GLOBAL_FIXTURE(CVcmiTestConfig);
-#endif

+ 12 - 15
test/StdInc.h

@@ -1,16 +1,13 @@
+/*
+ * StdInc.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
 #pragma once
-
-#include "../Global.h"
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-	#define BOOST_TEST_DYN_LINK
-#endif
-
-#ifdef _MSC_VER
-	#define BOOST_TEST_MODULE VcmiTest
-	#include <boost/test/unit_test.hpp>
-	#include "CVcmiTestConfig.h"
-	BOOST_GLOBAL_FIXTURE(CVcmiTestConfig);
-#endif
-
-
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "Global.h"

+ 118 - 0
test/battle/BattleHexTest.cpp

@@ -0,0 +1,118 @@
+/*
+ * BattleHexTest.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+
+#include "StdInc.h"
+#include "../lib/battle/BattleHex.h"
+
+TEST(BattleHexTest, getNeighbouringTiles){
+	BattleHex mainHex;
+	std::vector<BattleHex> neighbouringTiles;
+	mainHex.setXY(16,0);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 1);
+	mainHex.setXY(0,0);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 2);
+	mainHex.setXY(15,2);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 3);
+	mainHex.setXY(2,0);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 4);
+	mainHex.setXY(1,2);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 5);
+	mainHex.setXY(8,5);
+	neighbouringTiles = mainHex.neighbouringTiles();
+	EXPECT_EQ(neighbouringTiles.size(), 6);
+
+	ASSERT_TRUE(neighbouringTiles.size()==6 && mainHex==93);
+	EXPECT_EQ(neighbouringTiles.at(0), 75);
+	EXPECT_EQ(neighbouringTiles.at(1), 76);
+	EXPECT_EQ(neighbouringTiles.at(2), 94);
+	EXPECT_EQ(neighbouringTiles.at(3), 110);
+	EXPECT_EQ(neighbouringTiles.at(4), 109);
+	EXPECT_EQ(neighbouringTiles.at(5), 92);
+}
+
+TEST(BattleHexTest, getDistance){
+	BattleHex firstHex(0,0), secondHex(16,0);
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 16);
+	firstHex=0, secondHex=170;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 10);
+	firstHex=16, secondHex=181;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 10);
+	firstHex=186, secondHex=70;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 17);
+	firstHex=166, secondHex=39;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 11);
+	firstHex=25, secondHex=103;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 9);
+	firstHex=18, secondHex=71;
+	EXPECT_EQ((int)firstHex.getDistance(firstHex,secondHex), 4);
+}
+
+TEST(BattleHexTest, mutualPositions)
+{
+	BattleHex firstHex(0,0), secondHex(16,0);
+	firstHex=86, secondHex=68;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::TOP_LEFT);
+	secondHex=69;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::TOP_RIGHT);
+	secondHex=87;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::RIGHT);
+	secondHex=103;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::BOTTOM_RIGHT);
+	secondHex=102;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::BOTTOM_LEFT);
+	secondHex=85;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), BattleHex::EDir::LEFT);
+	secondHex=46;
+	EXPECT_EQ((int)firstHex.mutualPosition(firstHex,secondHex), -1);
+}
+
+TEST(BattleHexTest, getClosestTile)
+{
+	BattleHex mainHex(0);
+	std::set<BattleHex> possibilities;
+	possibilities.insert(3);
+	possibilities.insert(170);
+	possibilities.insert(100);
+	possibilities.insert(119);
+	possibilities.insert(186);
+
+	EXPECT_EQ(mainHex.getClosestTile(0,mainHex,possibilities), 3);
+	mainHex = 139;
+	EXPECT_EQ(mainHex.getClosestTile(1,mainHex,possibilities), 119);
+	mainHex = 16;
+	EXPECT_EQ(mainHex.getClosestTile(1,mainHex,possibilities), 100);
+	mainHex = 166;
+	EXPECT_EQ(mainHex.getClosestTile(0,mainHex,possibilities), 186);
+	mainHex = 76;
+	EXPECT_EQ(mainHex.getClosestTile(1,mainHex,possibilities), 3);
+	EXPECT_EQ(mainHex.getClosestTile(0,mainHex,possibilities), 100);
+}
+
+TEST(BattleHexTest, moveEDir)
+{
+	BattleHex mainHex(20);
+	mainHex.moveInDirection(BattleHex::EDir::BOTTOM_RIGHT);
+	EXPECT_EQ(mainHex, 37);
+	mainHex.moveInDirection(BattleHex::EDir::RIGHT);
+	EXPECT_EQ(mainHex, 38);
+	mainHex.moveInDirection(BattleHex::EDir::TOP_RIGHT);
+	EXPECT_EQ(mainHex, 22);
+	mainHex.moveInDirection(BattleHex::EDir::TOP_LEFT);
+	EXPECT_EQ(mainHex, 4);
+	mainHex.moveInDirection(BattleHex::EDir::LEFT);
+	EXPECT_EQ(mainHex, 3);
+	mainHex.moveInDirection(BattleHex::EDir::BOTTOM_LEFT);
+	EXPECT_EQ(mainHex, 20);
+}

+ 108 - 106
test/battle/CHealthTest.cpp

@@ -9,67 +9,57 @@
  */
 
 #include "StdInc.h"
-#include <boost/test/unit_test.hpp>
+#include "mock/mock_UnitHealthInfo.h"
 #include "../../lib/CStack.h"
 
+using namespace testing;
+
 static const int32_t UNIT_HEALTH = 123;
 static const int32_t UNIT_AMOUNT = 300;
 
-class CUnitHealthInfoMock : public IUnitHealthInfo
+class HealthTest : public ::testing::Test
 {
 public:
-	CUnitHealthInfoMock():
-		maxHealth(UNIT_HEALTH),
-		baseAmount(UNIT_AMOUNT),
-		health(this)
+	UnitHealthInfoMock mock;
+	HealthTest() : health(&mock)
+	{}
+
+	void setDefaultExpectations()
 	{
-		health.init();
+		EXPECT_CALL(mock, unitMaxHealth()).WillRepeatedly(Return(UNIT_HEALTH));
+		EXPECT_CALL(mock, unitBaseAmount()).WillRepeatedly(Return(UNIT_AMOUNT));
 	}
-
-	int32_t maxHealth;
-	int32_t baseAmount;
-
 	CHealth health;
-
-	int32_t unitMaxHealth() const override
-	{
-		return maxHealth;
-	};
-
-	int32_t unitBaseAmount() const override
-	{
-		return baseAmount;
-	};
 };
 
-static void checkTotal(const CHealth & health, const CUnitHealthInfoMock & mock)
+static void checkTotal(const CHealth & health, const UnitHealthInfoMock & mock)
 {
-	BOOST_CHECK_EQUAL(health.total(), mock.maxHealth * mock.baseAmount);
+	EXPECT_EQ(health.total(), mock.unitMaxHealth() * mock.unitBaseAmount());
 }
 
-static void checkEmptyHealth(const CHealth & health, const CUnitHealthInfoMock & mock)
+static void checkEmptyHealth(const CHealth & health, const UnitHealthInfoMock & mock)
 {
 	checkTotal(health, mock);
-	BOOST_CHECK_EQUAL(health.getCount(), 0);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), 0);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
-	BOOST_CHECK_EQUAL(health.available(), 0);
+	EXPECT_EQ(health.getCount(), 0);
+	EXPECT_EQ(health.getFirstHPleft(), 0);
+	EXPECT_EQ(health.getResurrected(), 0);
+	EXPECT_EQ(health.available(), 0);
 }
 
-static void checkFullHealth(const CHealth & health, const CUnitHealthInfoMock & mock)
+static void checkFullHealth(const CHealth & health, const UnitHealthInfoMock & mock)
 {
 	checkTotal(health, mock);
-	BOOST_CHECK_EQUAL(health.getCount(), mock.baseAmount);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), mock.maxHealth);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
-	BOOST_CHECK_EQUAL(health.available(), mock.maxHealth * mock.baseAmount);
+	EXPECT_EQ(health.getCount(), mock.unitBaseAmount());
+	EXPECT_EQ(health.getFirstHPleft(), mock.unitMaxHealth());
+	EXPECT_EQ(health.getResurrected(), 0);
+	EXPECT_EQ(health.available(), mock.unitMaxHealth() * mock.unitBaseAmount());
 }
 
 static void checkDamage(CHealth & health, const int32_t initialDamage, const int32_t expectedDamage)
 {
 	int32_t damage = initialDamage;
 	health.damage(damage);
-	BOOST_CHECK_EQUAL(damage, expectedDamage);
+	EXPECT_EQ(damage, expectedDamage);
 }
 
 static void checkNormalDamage(CHealth & health, const int32_t initialDamage)
@@ -86,155 +76,167 @@ static void checkHeal(CHealth & health, EHealLevel level, EHealPower power, cons
 {
 	int32_t heal = initialHeal;
 	health.heal(heal, level, power);
-	BOOST_CHECK_EQUAL(heal, expectedHeal);
+	EXPECT_EQ(heal, expectedHeal);
 }
 
-BOOST_AUTO_TEST_SUITE(CHealthTest_Suite)
-
-BOOST_AUTO_TEST_CASE(empty)
+TEST_F(HealthTest, empty)
 {
-	CUnitHealthInfoMock uhi;
-	CHealth health(&uhi);
-	checkEmptyHealth(health, uhi);
+	setDefaultExpectations();
+
+	checkEmptyHealth(health, mock);
 
 	health.init();
-	checkFullHealth(health, uhi);
+	checkFullHealth(health, mock);
 
 	health.reset();
-	checkEmptyHealth(health, uhi);
+	checkEmptyHealth(health, mock);
 }
 
-BOOST_FIXTURE_TEST_CASE(damage, CUnitHealthInfoMock)
+
+TEST_F(HealthTest, damage)
 {
+	setDefaultExpectations();
+
+	health.init();
+
 	checkNormalDamage(health, 0);
-	checkFullHealth(health, *this);
+	checkFullHealth(health, mock);
 
-	checkNormalDamage(health, maxHealth - 1);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), 1);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	checkNormalDamage(health, mock.unitMaxHealth() - 1);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), 1);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkNormalDamage(health, 1);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkNormalDamage(health, UNIT_HEALTH * (UNIT_AMOUNT - 1));
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 
 	checkNoDamage(health, 1337);
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 }
 
-BOOST_FIXTURE_TEST_CASE(heal, CUnitHealthInfoMock)
+TEST_F(HealthTest, heal)
 {
+	setDefaultExpectations();
+
+	health.init();
+
 	checkNormalDamage(health, 99);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH-99);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH-99);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkHeal(health, EHealLevel::HEAL, EHealPower::PERMANENT, 9, 9);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH-90);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH-90);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::ONE_BATTLE, 40, 40);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH-50);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH-50);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkHeal(health, EHealLevel::OVERHEAL, EHealPower::PERMANENT, 50, 50);
-	checkFullHealth(health, *this);
+	checkFullHealth(health, mock);
 }
 
-BOOST_FIXTURE_TEST_CASE(resurrectOneBattle, CUnitHealthInfoMock)
+TEST_F(HealthTest, resurrectOneBattle)
 {
+	setDefaultExpectations();
+	health.init();
+
 	checkNormalDamage(health, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::ONE_BATTLE, UNIT_HEALTH, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 1);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 1);
 
 	checkNormalDamage(health, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	health.init();
 
 	checkNormalDamage(health, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	health.takeResurrected();
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	health.init();
 
 	checkNormalDamage(health, UNIT_HEALTH * UNIT_AMOUNT);
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::ONE_BATTLE, UNIT_HEALTH * UNIT_AMOUNT, UNIT_HEALTH * UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), UNIT_AMOUNT);
 
 	health.takeResurrected();
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 }
 
-BOOST_FIXTURE_TEST_CASE(resurrectPermanent, CUnitHealthInfoMock)
+TEST_F(HealthTest, resurrectPermanent)
 {
+	setDefaultExpectations();
+	health.init();
+
 	checkNormalDamage(health, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::PERMANENT, UNIT_HEALTH, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	checkNormalDamage(health, UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getCount(), UNIT_AMOUNT - 1);
-	BOOST_CHECK_EQUAL(health.getFirstHPleft(), UNIT_HEALTH);
-	BOOST_CHECK_EQUAL(health.getResurrected(), 0);
+	EXPECT_EQ(health.getCount(), UNIT_AMOUNT - 1);
+	EXPECT_EQ(health.getFirstHPleft(), UNIT_HEALTH);
+	EXPECT_EQ(health.getResurrected(), 0);
 
 	health.init();
 
 	checkNormalDamage(health, UNIT_HEALTH * UNIT_AMOUNT);
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::PERMANENT, UNIT_HEALTH * UNIT_AMOUNT, UNIT_HEALTH * UNIT_AMOUNT);
-	checkFullHealth(health, *this);
+	checkFullHealth(health, mock);
 
 	health.takeResurrected();
-	checkFullHealth(health, *this);
+	checkFullHealth(health, mock);
 }
 
-BOOST_FIXTURE_TEST_CASE(singleUnitStack, CUnitHealthInfoMock)
+TEST_F(HealthTest, singleUnitStack)
 {
 	//related to issue 2612
 
 	//one Titan
-	baseAmount = 1;
-	maxHealth = 300;
+
+	EXPECT_CALL(mock, unitMaxHealth()).WillRepeatedly(Return(300));
+	EXPECT_CALL(mock, unitBaseAmount()).WillRepeatedly(Return(1));
 
 	health.init();
 
 	checkDamage(health, 1000, 300);
-	checkEmptyHealth(health, *this);
+	checkEmptyHealth(health, mock);
 
 	checkHeal(health, EHealLevel::RESURRECT, EHealPower::PERMANENT, 300, 300);
-	checkFullHealth(health, *this);
+	checkFullHealth(health, mock);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
-

+ 1 - 0
test/googletest

@@ -0,0 +1 @@
+Subproject commit 4bab34d2084259cba67f3bfb51217c10d606e175

+ 20 - 0
test/main.cpp

@@ -0,0 +1,20 @@
+/*
+ * main.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+
+#include "StdInc.h"
+#include "CVcmiTestConfig.h"
+#include "../lib/filesystem/CMemoryBuffer.h"
+
+int main(int argc, char ** argv)
+{
+	::testing::InitGoogleTest(&argc, argv);
+	CVcmiTestConfig test;
+	return RUN_ALL_TESTS();
+}

+ 15 - 30
test/CMapEditManagerTest.cpp → test/map/CMapEditManagerTest.cpp

@@ -9,7 +9,6 @@
  */
 
 #include "StdInc.h"
-#include <boost/test/unit_test.hpp>
 
 #include "../lib/filesystem/ResourceID.h"
 #include "../lib/mapping/CMapService.h"
@@ -20,11 +19,9 @@
 #include "../lib/CRandomGenerator.h"
 #include "../lib/VCMI_Lib.h"
 
-BOOST_AUTO_TEST_SUITE(CMapEditManager_Suite)
 
-BOOST_AUTO_TEST_CASE(DrawTerrain_Type)
+TEST(MapManager, DrawTerrain_Type)
 {
-	logGlobal->info("CMapEditManager_DrawTerrain_Type start");
 	try
 	{
 		auto map = make_unique<CMap>();
@@ -40,17 +37,17 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_Type)
 		static const int3 squareCheck[] = { int3(5,5,0), int3(5,4,0), int3(4,4,0), int3(4,5,0) };
 		for(int i = 0; i < ARRAY_COUNT(squareCheck); ++i)
 		{
-			BOOST_CHECK(map->getTile(squareCheck[i]).terType == ETerrainType::GRASS);
+			EXPECT_EQ(map->getTile(squareCheck[i]).terType, ETerrainType::GRASS);
 		}
 
 		// Concat to square
 		editManager->getTerrainSelection().select(int3(6, 5, 0));
 		editManager->drawTerrain(ETerrainType::GRASS);
-		BOOST_CHECK(map->getTile(int3(6, 4, 0)).terType == ETerrainType::GRASS);
+		EXPECT_EQ(map->getTile(int3(6, 4, 0)).terType, ETerrainType::GRASS);
 		editManager->getTerrainSelection().select(int3(6, 5, 0));
 		editManager->drawTerrain(ETerrainType::LAVA);
-		BOOST_CHECK(map->getTile(int3(4, 4, 0)).terType == ETerrainType::GRASS);
-		BOOST_CHECK(map->getTile(int3(7, 4, 0)).terType == ETerrainType::LAVA);
+		EXPECT_EQ(map->getTile(int3(4, 4, 0)).terType, ETerrainType::GRASS);
+		EXPECT_EQ(map->getTile(int3(7, 4, 0)).terType, ETerrainType::LAVA);
 
 		// Special case water,rock
 		editManager->getTerrainSelection().selectRange(MapRect(int3(10, 10, 0), 10, 5));
@@ -59,18 +56,18 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_Type)
 		editManager->drawTerrain(ETerrainType::GRASS);
 		editManager->getTerrainSelection().select(int3(21, 16, 0));
 		editManager->drawTerrain(ETerrainType::GRASS);
-		BOOST_CHECK(map->getTile(int3(20, 15, 0)).terType == ETerrainType::GRASS);
+		EXPECT_EQ(map->getTile(int3(20, 15, 0)).terType, ETerrainType::GRASS);
 
 		// Special case non water,rock
 		static const int3 diagonalCheck[] = { int3(31,42,0), int3(32,42,0), int3(32,43,0), int3(33,43,0), int3(33,44,0),
-											  int3(34,44,0), int3(34,45,0), int3(35,45,0), int3(35,46,0), int3(36,46,0),
-											  int3(36,47,0), int3(37,47,0)};
+											int3(34,44,0), int3(34,45,0), int3(35,45,0), int3(35,46,0), int3(36,46,0),
+											int3(36,47,0), int3(37,47,0)};
 		for(int i = 0; i < ARRAY_COUNT(diagonalCheck); ++i)
 		{
 			editManager->getTerrainSelection().select(diagonalCheck[i]);
 		}
 		editManager->drawTerrain(ETerrainType::GRASS);
-		BOOST_CHECK(map->getTile(int3(35, 44, 0)).terType == ETerrainType::WATER);
+		EXPECT_EQ(map->getTile(int3(35, 44, 0)).terType, ETerrainType::WATER);
 
 		// Rock case
 		editManager->getTerrainSelection().selectRange(MapRect(int3(1, 1, 1), 15, 15));
@@ -79,7 +76,7 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_Type)
 								int3(8, 7, 1), int3(4, 8, 1), int3(5, 8, 1), int3(6, 8, 1)});
 		editManager->getTerrainSelection().setSelection(vec);
 		editManager->drawTerrain(ETerrainType::ROCK);
-		BOOST_CHECK(map->getTile(int3(5, 6, 1)).terType == ETerrainType::ROCK || map->getTile(int3(7, 8, 1)).terType == ETerrainType::ROCK);
+		EXPECT_TRUE(map->getTile(int3(5, 6, 1)).terType == ETerrainType::ROCK || map->getTile(int3(7, 8, 1)).terType == ETerrainType::ROCK);
 
 		//todo: add checks here and enable, also use smaller size
 		#if 0
@@ -104,23 +101,19 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_Type)
 	}
 	catch(const std::exception & e)
 	{
-		logGlobal->error("CMapEditManager_DrawTerrain_Type crash");
-		logGlobal->error(e.what());
+		FAIL()<<e.what();
 		throw;
 	}
-	logGlobal->info("CMapEditManager_DrawTerrain_Type finish");
 }
 
-BOOST_AUTO_TEST_CASE(DrawTerrain_View)
+TEST(MapManager, DrawTerrain_View)
 {
-	logGlobal->info("CMapEditManager_DrawTerrain_View start");
 	try
 	{
 		const ResourceID testMap("test/TerrainViewTest", EResType::MAP);
 		// Load maps and json config
 		const auto originalMap = CMapService::loadMap(testMap);
 		auto map = CMapService::loadMap(testMap);
-		logGlobal->info("Loaded test map successfully.");
 
 		// Validate edit manager
 		auto editManager = map->getEditManager();
@@ -148,10 +141,6 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_View)
 				const auto & posVector = posNode.Vector();
 				if(posVector.size() != 3) throw std::runtime_error("A position should consist of three values x,y,z. Continue with next position.");
 				int3 pos(posVector[0].Float(), posVector[1].Float(), posVector[2].Float());
-#if 0
-				logGlobal->trace("Test pattern '%s' on position x '%d', y '%d', z '%d'.", patternStr, pos.x, pos.y, pos.z);
-				CTerrainViewPatternUtils::printDebuggingInfoAboutTile(map.get(), pos);
-#endif // 0
 				const auto & originalTile = originalMap->getTile(pos);
 				editManager->getTerrainSelection().selectRange(MapRect(pos, 1, 1));
 				editManager->drawTerrain(originalTile.terType, &gen);
@@ -165,19 +154,15 @@ BOOST_AUTO_TEST_CASE(DrawTerrain_View)
 						break;
 					}
 				}
-				BOOST_CHECK(isInRange);
+				EXPECT_TRUE(isInRange);
 				if(!isInRange)
-					logGlobal->error("No or invalid pattern found for current position.");
+					FAIL()<<("No or invalid pattern found for current position.");
 			}
 		}
 	}
 	catch(const std::exception & e)
 	{
-		logGlobal->info("CMapEditManager_DrawTerrain_View crash");
-		logGlobal->info(e.what());
+		FAIL()<<e.what();
 		throw;
 	}
-	logGlobal->info("CMapEditManager_DrawTerrain_View finish");
 }
-
-BOOST_AUTO_TEST_SUITE_END()

+ 7 - 24
test/CMapFormatTest.cpp → test/map/CMapFormatTest.cpp

@@ -9,8 +9,6 @@
  */
 #include "StdInc.h"
 
-#include <boost/test/unit_test.hpp>
-
 #include "../lib/filesystem/CMemoryBuffer.h"
 #include "../lib/filesystem/Filesystem.h"
 
@@ -25,12 +23,10 @@
 
 static const int TEST_RANDOM_SEED = 1337;
 
-BOOST_AUTO_TEST_SUITE(MapFormat_Suite)
 
-BOOST_AUTO_TEST_CASE(Random)
+TEST(MapFormat, Random)
 {
-	logGlobal->info("MapFormat_Random start");
-	BOOST_TEST_CHECKPOINT("MapFormat_Random start");
+	SCOPED_TRACE("MapFormat_Random start");
 	std::unique_ptr<CMap> initialMap;
 
 	CMapGenOptions opt;
@@ -49,14 +45,14 @@ BOOST_AUTO_TEST_CASE(Random)
 
 	initialMap = gen.generate(&opt, TEST_RANDOM_SEED);
 	initialMap->name = "Test";
-	BOOST_TEST_CHECKPOINT("MapFormat_Random generated");
+	SCOPED_TRACE("MapFormat_Random generated");
 
 	CMemoryBuffer serializeBuffer;
 	{
 		CMapSaverJson saver(&serializeBuffer);
 		saver.saveMap(initialMap);
 	}
-	BOOST_TEST_CHECKPOINT("MapFormat_Random serialized");
+	SCOPED_TRACE("MapFormat_Random serialized");
 	#if 1
 	{
 		auto path = VCMIDirs::get().userDataPath()/"test_random.vmap";
@@ -66,12 +62,8 @@ BOOST_AUTO_TEST_CASE(Random)
 		tmp.write((const char *)serializeBuffer.getBuffer().data(),serializeBuffer.getSize());
 		tmp.flush();
 		tmp.close();
-
-		logGlobal->info("Test map has been saved to:");
-		logGlobal->info(path.string());
 	}
-	BOOST_TEST_CHECKPOINT("MapFormat_Random saved");
-
+	SCOPED_TRACE("MapFormat_Random saved");
 	#endif // 1
 
 	serializeBuffer.seek(0);
@@ -82,8 +74,7 @@ BOOST_AUTO_TEST_CASE(Random)
 		MapComparer c;
 		c(serialized, initialMap);
 	}
-
-	logGlobal->info("MapFormat_Random finish");
+	SCOPED_TRACE("MapFormat_Random finish");
 }
 
 static JsonNode getFromArchive(CZipLoader & archive, const std::string & archiveFilename)
@@ -116,10 +107,8 @@ static void addToArchive(CZipSaver & saver, const JsonNode & data, const std::st
 	}
 }
 
-BOOST_AUTO_TEST_CASE(Objects)
+TEST(MapFormat, Objects)
 {
-	logGlobal->info("MapFormat_Objects start");
-
 	static const std::string MAP_DATA_PATH = "test/ObjectPropertyTest/";
 
 	const JsonNode initialHeader(ResourceID(MAP_DATA_PATH+"header.json"));
@@ -177,8 +166,6 @@ BOOST_AUTO_TEST_CASE(Objects)
 		tmp.write((const char *)serializeBuffer.getBuffer().data(),serializeBuffer.getSize());
 		tmp.flush();
 		tmp.close();
-
-		logGlobal->infoStream() << "Test map has been saved to " << path;
 	}
 
 	{
@@ -200,8 +187,4 @@ BOOST_AUTO_TEST_CASE(Objects)
 		JsonMapComparer c;
 		c.compareTerrain("underground", actualUnderground, expectedUnderground);
 	}
-
-	logGlobal->info("MapFormat_Objects finish");
 }
-
-BOOST_AUTO_TEST_SUITE_END()

+ 35 - 48
test/MapComparer.cpp → test/map/MapComparer.cpp

@@ -9,29 +9,27 @@
  */
 #include "StdInc.h"
 
-#include <boost/test/unit_test.hpp>
-
 #include "MapComparer.h"
 
 #include "../lib/ScopeGuard.h"
 #include "../lib/mapping/CMap.h"
 
-#define VCMI_CHECK_FIELD_EQUAL_P(field) BOOST_CHECK_EQUAL(actual->field, expected->field)
+#define VCMI_CHECK_FIELD_EQUAL_P(field) EXPECT_EQ(actual->field, expected->field)
 
-#define VCMI_CHECK_FIELD_EQUAL(field) BOOST_CHECK_EQUAL(actual.field, expected.field)
+#define VCMI_CHECK_FIELD_EQUAL(field) EXPECT_EQ(actual.field, expected.field)
 
-#define VCMI_REQUIRE_FIELD_EQUAL_P(field) BOOST_REQUIRE_EQUAL(actual->field, expected->field)
-#define VCMI_REQUIRE_FIELD_EQUAL(field) BOOST_REQUIRE_EQUAL(actual.field, expected.field)
+#define VCMI_REQUIRE_FIELD_EQUAL_P(field) ASSERT_EQ(actual->field, expected->field)
+#define VCMI_REQUIRE_FIELD_EQUAL(field) ASSERT_EQ(actual.field, expected.field)
 
 template <class T>
 void checkEqual(const T & actual, const T & expected)
 {
-	BOOST_CHECK_EQUAL(actual, expected)	;
+	EXPECT_EQ(actual, expected)	;
 }
 
 void checkEqual(const std::vector<bool> & actual, const std::vector<bool> & expected)
 {
-	BOOST_CHECK_EQUAL(actual.size(), expected.size());
+	EXPECT_EQ(actual.size(), expected.size());
 
 	for(auto actualIt = actual.begin(), expectedIt = expected.begin(); actualIt != actual.end() && expectedIt != expected.end(); actualIt++, expectedIt++)
 	{
@@ -42,7 +40,7 @@ void checkEqual(const std::vector<bool> & actual, const std::vector<bool> & expe
 template <class Element>
 void checkEqual(const std::vector<Element> & actual, const std::vector<Element> & expected)
 {
-	BOOST_CHECK_EQUAL(actual.size(), expected.size());
+	EXPECT_EQ(actual.size(), expected.size());
 
 	for(auto actualIt = actual.begin(), expectedIt = expected.begin(); actualIt != actual.end() && expectedIt != expected.end(); actualIt++, expectedIt++)
 	{
@@ -53,12 +51,12 @@ void checkEqual(const std::vector<Element> & actual, const std::vector<Element>
 template <class Element>
 void checkEqual(const std::set<Element> & actual, const std::set<Element> & expected)
 {
-	BOOST_CHECK_EQUAL(actual.size(), expected.size());
+	EXPECT_EQ(actual.size(), expected.size());
 
 	for(auto elem : expected)
 	{
 		if(!vstd::contains(actual, elem))
-			BOOST_ERROR("Required element not found "+boost::to_string(elem));
+			FAIL() << "Required element not found "+boost::to_string(elem);
 	}
 }
 
@@ -91,12 +89,12 @@ void checkEqual(const PlayerInfo & actual, const PlayerInfo & expected)
 	VCMI_CHECK_FIELD_EQUAL(hasRandomHero);
 }
 
-void checkEqual(const EventExpression & actual,  const EventExpression & expected)
+void checkEqual(const EventExpression & actual, const EventExpression & expected)
 {
 	//todo: checkEventExpression
 }
 
-void checkEqual(const TriggeredEvent & actual,  const TriggeredEvent & expected)
+void checkEqual(const TriggeredEvent & actual, const TriggeredEvent & expected)
 {
 	VCMI_CHECK_FIELD_EQUAL(identifier);
 	VCMI_CHECK_FIELD_EQUAL(description);
@@ -142,8 +140,8 @@ void checkEqual(const TerrainTile & actual, const TerrainTile & expected)
 	VCMI_REQUIRE_FIELD_EQUAL(roadDir);
 	VCMI_REQUIRE_FIELD_EQUAL(extTileFlags);
 
-	BOOST_REQUIRE_EQUAL(actual.blockingObjects.size(), expected.blockingObjects.size());
-	BOOST_REQUIRE_EQUAL(actual.visitableObjects.size(), expected.visitableObjects.size());
+	ASSERT_EQ(actual.blockingObjects.size(), expected.blockingObjects.size());
+	ASSERT_EQ(actual.visitableObjects.size(), expected.visitableObjects.size());
 
 	VCMI_REQUIRE_FIELD_EQUAL(visitable);
 	VCMI_REQUIRE_FIELD_EQUAL(blocked);
@@ -179,7 +177,7 @@ void MapComparer::compareHeader()
 
 	auto sortByIdentifier = [](const TriggeredEvent & lhs, const TriggeredEvent & rhs) -> bool
 	{
-		return lhs.identifier  < rhs.identifier;
+		return lhs.identifier < rhs.identifier;
 	};
 	boost::sort (actualEvents, sortByIdentifier);
 	boost::sort (expectedEvents, sortByIdentifier);
@@ -197,18 +195,18 @@ void MapComparer::compareOptions()
 	checkEqual(actual->allowedArtifact, expected->allowedArtifact);
 	checkEqual(actual->allowedSpell, expected->allowedSpell);
 
-	//todo: compareOptions  events
+	//todo: compareOptions events
 }
 
 void MapComparer::compareObject(const CGObjectInstance * actual, const CGObjectInstance * expected)
 {
-	BOOST_CHECK_EQUAL(actual->instanceName, expected->instanceName);
-	BOOST_CHECK_EQUAL(typeid(actual).name(), typeid(expected).name());//todo: remove and use just comparison
+	EXPECT_EQ(actual->instanceName, expected->instanceName);
+	EXPECT_EQ(typeid(actual).name(), typeid(expected).name());//todo: remove and use just comparison
 
 	std::string actualFullID = boost::to_string(boost::format("%s(%d)|%s(%d) %d") % actual->typeName % actual->ID % actual->subTypeName % actual->subID % actual->tempOwner);
 	std::string expectedFullID = boost::to_string(boost::format("%s(%d)|%s(%d) %d") % expected->typeName % expected->ID % expected->subTypeName % expected->subID % expected->tempOwner);
 
-	BOOST_CHECK_EQUAL(actualFullID, expectedFullID);
+	EXPECT_EQ(actualFullID, expectedFullID);
 
 	VCMI_CHECK_FIELD_EQUAL_P(pos);
 	checkEqual(actual->appearance, expected->appearance);
@@ -216,24 +214,24 @@ void MapComparer::compareObject(const CGObjectInstance * actual, const CGObjectI
 
 void MapComparer::compareObjects()
 {
-	BOOST_CHECK_EQUAL(actual->objects.size(), expected->objects.size());
+	EXPECT_EQ(actual->objects.size(), expected->objects.size());
 
 	for(size_t idx = 0; idx < expected->objects.size(); idx++)
 	{
 		auto expectedObject = expected->objects[idx];
 
-		BOOST_REQUIRE_EQUAL(idx, expectedObject->id.getNum());
+		ASSERT_EQ(idx, expectedObject->id.getNum());
 
 		{
 			auto it = expected->instanceNames.find(expectedObject->instanceName);
 
-			BOOST_REQUIRE(it != expected->instanceNames.end());
+			ASSERT_NE(it, expected->instanceNames.end());
 		}
 
 		{
 			auto it = actual->instanceNames.find(expectedObject->instanceName);
 
-			BOOST_REQUIRE(it != actual->instanceNames.end());
+			ASSERT_NE(it, actual->instanceNames.end());
 
 			auto actualObject = it->second;
 
@@ -251,17 +249,16 @@ void MapComparer::compareTerrain()
 		for(int y = 0; y < expected->height; y++)
 		{
 			int3 coord(x,y,0);
-			BOOST_TEST_CHECKPOINT(coord);
-
+			SCOPED_TRACE(coord);
 			checkEqual(actual->getTile(coord), expected->getTile(coord));
 		}
 }
 
 void MapComparer::compare()
 {
-	BOOST_REQUIRE_NE((void *) actual, (void *) expected); //should not point to the same object
-	BOOST_REQUIRE_MESSAGE(actual != nullptr, "Actual map is not defined");
-	BOOST_REQUIRE_MESSAGE(expected != nullptr, "Expected map is not defined");
+	ASSERT_NE((void *) actual, (void *) expected); //should not point to the same object
+	ASSERT_TRUE(actual != nullptr) << "Actual map is not defined";
+	ASSERT_TRUE(expected != nullptr) << "Expected map is not defined";
 
 	compareHeader();
 	compareOptions();
@@ -269,7 +266,7 @@ void MapComparer::compare()
 	compareTerrain();
 }
 
-void MapComparer::operator() (const std::unique_ptr<CMap>& actual, const std::unique_ptr<CMap>&  expected)
+void MapComparer::operator() (const std::unique_ptr<CMap>& actual, const std::unique_ptr<CMap>& expected)
 {
 	this->actual = actual.get();
 	this->expected = expected.get();
@@ -301,12 +298,7 @@ std::string JsonMapComparer::buildMessage(const std::string & message)
 
 void JsonMapComparer::addError(const std::string & message)
 {
-	BOOST_ERROR(buildMessage(message));
-}
-
-void JsonMapComparer::addWarning(const std::string & message)
-{
-	BOOST_WARN_MESSAGE(false, buildMessage(message));
+	FAIL()<<buildMessage(message);
 }
 
 bool JsonMapComparer::isEmpty(const JsonNode & value)
@@ -327,7 +319,7 @@ bool JsonMapComparer::isEmpty(const JsonNode & value)
 		return value.Struct().empty();
 		break;
 	default:
-		BOOST_FAIL("Unknown Json type");
+		EXPECT_TRUE(false) << "Unknown Json type";
 		return false;
 	}
 }
@@ -335,9 +327,9 @@ bool JsonMapComparer::isEmpty(const JsonNode & value)
 void JsonMapComparer::check(const bool condition, const std::string & message)
 {
 	if(strict)
-		BOOST_REQUIRE_MESSAGE(condition, buildMessage(message));
+		ASSERT_TRUE(condition) << buildMessage(message);
 	else
-		BOOST_CHECK_MESSAGE(condition, buildMessage(message));
+		EXPECT_TRUE(condition) << buildMessage(message);
 }
 
 void JsonMapComparer::checkEqualInteger(const si64 actual, const si64 expected)
@@ -366,7 +358,7 @@ void JsonMapComparer::checkEqualString(const std::string & actual, const std::st
 
 void JsonMapComparer::checkEqualJson(const JsonMap & actual, const JsonMap & expected)
 {
-    for(const auto & p : expected)
+	for(const auto & p : expected)
 		checkStructField(actual, p.first, p.second);
 	for(const auto & p : actual)
 		checkExcessStructField(p.second, p.first, expected);
@@ -421,7 +413,7 @@ void JsonMapComparer::checkEqualJson(const JsonNode & actual, const JsonNode & e
 			checkEqualInteger(actual.Integer(), expected.Integer());
 			break;
 		default:
-			BOOST_FAIL("Unknown Json type");
+			FAIL() << "Unknown Json type";
 			break;
 		}
 	}
@@ -433,9 +425,7 @@ void JsonMapComparer::checkExcessStructField(const JsonNode & actualValue, const
 
 	if(!vstd::contains(expected, name))
 	{
-		if(isEmpty(actualValue))
-			addWarning("excess");
-		else
+		if(!isEmpty(actualValue))
 			addError("excess");
 	}
 }
@@ -443,12 +433,9 @@ void JsonMapComparer::checkExcessStructField(const JsonNode & actualValue, const
 void JsonMapComparer::checkStructField(const JsonMap & actual, const std::string & name, const JsonNode & expectedValue)
 {
 	auto guard = pushName(name);
-
 	if(!vstd::contains(actual, name))
 	{
-		if(isEmpty(expectedValue))
-			addWarning("missing");
-		else
+		if(!isEmpty(expectedValue))
 			addError("missing");
 	}
 	else

+ 1 - 2
test/MapComparer.h → test/map/MapComparer.h

@@ -52,7 +52,6 @@ struct JsonMapComparer
 	std::string buildMessage(const std::string & message);
 
 	void addError(const std::string & message);
-	void addWarning(const std::string & message);
 
 	bool isEmpty(const JsonNode & value);
 
@@ -69,7 +68,7 @@ struct JsonMapComparer
 	void checkEqualJson(const JsonMap & actual, const JsonMap & expected);
 	void checkEqualJson(const JsonVector & actual, const JsonVector & expected);
 
-    void compareHeader(const JsonNode & actual, const JsonNode & expected);
+	void compareHeader(const JsonNode & actual, const JsonNode & expected);
 	void compareObjects(const JsonNode & actual, const JsonNode & expected);
 	void compareTerrain(const std::string & levelName, const JsonNode & actual, const JsonNode & expected);
 };

+ 22 - 0
test/mock/mock_UnitHealthInfo.h

@@ -0,0 +1,22 @@
+/*
+ * mock_UnitHealthInfo.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+
+#include "StdInc.h"
+#include "../../lib/CStack.h"
+
+class UnitHealthInfoMock : public IUnitHealthInfo
+{
+public:
+	MOCK_CONST_METHOD0(unitMaxHealth, int32_t());
+	MOCK_CONST_METHOD0(unitBaseAmount, int32_t());
+};
+
+
+