From 34513cf16b955be45361304f89dd76f969ef1a62 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 19 Aug 2012 22:23:46 +0300 Subject: [PATCH 1/5] Added support for code coverage checking and unittests. Added support for code coverage checking with gcov and unittests with Google C++ unittest and GMock frameworks. Signed-off-by: Lukasz Gromanowski --- CMakeLists.txt | 7 ++ apps/esmtool/CMakeLists.txt | 5 + apps/launcher/CMakeLists.txt | 5 + apps/mwiniimporter/CMakeLists.txt | 4 + apps/openmw/CMakeLists.txt | 5 + apps/openmw_test_suite/CMakeLists.txt | 24 +++++ .../components/misc/test_stringops.cpp | 7 ++ apps/openmw_test_suite/openmw_test_suite.cpp | 12 +++ cmake/FindGMock.cmake | 91 +++++++++++++++++++ 9 files changed, 160 insertions(+) create mode 100644 apps/openmw_test_suite/CMakeLists.txt create mode 100644 apps/openmw_test_suite/components/misc/test_stringops.cpp create mode 100644 apps/openmw_test_suite/openmw_test_suite.cpp create mode 100644 cmake/FindGMock.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ab235de24..df05b72e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries option(BUILD_ESMTOOL "build ESM inspector" ON) option(BUILD_LAUNCHER "build Launcher" ON) option(BUILD_MWINIIMPORTER "build MWiniImporter" ON) +option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF) +option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock frameworks" OFF) # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" OFF) @@ -464,6 +466,11 @@ if (BUILD_MWINIIMPORTER) add_subdirectory( apps/mwiniimporter ) endif() +# UnitTests +if (BUILD_UNITTESTS) + add_subdirectory( apps/openmw_test_suite ) +endif() + if (WIN32) if (MSVC) if (USE_DEBUG_CONSOLE) diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index af3dc090e..bd397d554 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -17,3 +17,8 @@ target_link_libraries(esmtool # find_library(CARBON_FRAMEWORK Carbon) # target_link_libraries(openmw ${CARBON_FRAMEWORK}) #endif (APPLE) + +if (BUILD_WITH_CODE_COVERAGE) + add_definitions (--coverage) + target_link_libraries(esmtool gcov) +endif() diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index ed3559fdc..2bc43db80 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -100,3 +100,8 @@ else() configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.cfg") endif() + +if (BUILD_WITH_CODE_COVERAGE) + add_definitions (--coverage) + target_link_libraries(omwlauncher gcov) +endif() diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index 2a8c0f5fe..deab88ce2 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -18,3 +18,7 @@ target_link_libraries(mwiniimport components ) +if (BUILD_WITH_CODE_COVERAGE) + add_definitions (--coverage) + target_link_libraries(mwiniimport gcov) +endif() diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 02fe0b72c..326b4d35f 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -120,3 +120,8 @@ endif(APPLE) if(DPKG_PROGRAM) INSTALL(TARGETS openmw RUNTIME DESTINATION games COMPONENT openmw) endif(DPKG_PROGRAM) + +if (BUILD_WITH_CODE_COVERAGE) + add_definitions (--coverage) + target_link_libraries(openmw gcov) +endif() diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt new file mode 100644 index 000000000..afe0f30da --- /dev/null +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -0,0 +1,24 @@ +# TODO: This should not be needed, check how it was done in FindGTEST +set(GMOCK_ROOT "/usr/include") +set(GMOCK_BUILD "/usr/lib") + +find_package(GTest REQUIRED) +find_package(GMock REQUIRED) + +if (GTEST_FOUND AND GMOCK_FOUND) + + include_directories(${GTEST_INCLUDE_DIRS}) + include_directories(${GMOCK_INCLUDE_DIRS}) + + file(GLOB UNITTEST_SRC_FILES + components/misc/*.cpp + ) + + source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) + + add_executable(openmw_test_suite openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) + + target_link_libraries(openmw_test_suite ${GMOCK_BOTH_LIBRARIES} ${GTEST_BOTH_LIBRARIES}) +endif() + + diff --git a/apps/openmw_test_suite/components/misc/test_stringops.cpp b/apps/openmw_test_suite/components/misc/test_stringops.cpp new file mode 100644 index 000000000..b12584196 --- /dev/null +++ b/apps/openmw_test_suite/components/misc/test_stringops.cpp @@ -0,0 +1,7 @@ +#include + +TEST(simple_test, dummy) +{ + EXPECT_EQ(true, true); +} + diff --git a/apps/openmw_test_suite/openmw_test_suite.cpp b/apps/openmw_test_suite/openmw_test_suite.cpp new file mode 100644 index 000000000..0a09b3028 --- /dev/null +++ b/apps/openmw_test_suite/openmw_test_suite.cpp @@ -0,0 +1,12 @@ +#include +#include + + +int main(int argc, char** argv) { + // The following line causes Google Mock to throw an exception on failure, + // which will be interpreted by your testing framework as a test failure. + ::testing::GTEST_FLAG(throw_on_failure) = true; + ::testing::InitGoogleMock(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/cmake/FindGMock.cmake b/cmake/FindGMock.cmake new file mode 100644 index 000000000..eda7d4d72 --- /dev/null +++ b/cmake/FindGMock.cmake @@ -0,0 +1,91 @@ +# Locate the Google C++ Mocking Framework. +# +# Defines the following variables: +# +# GMOCK_FOUND - Found the Google Mocking framework +# GMOCK_INCLUDE_DIRS - Include directories +# +# Also defines the library variables below as normal +# variables. These contain debug/optimized keywords when +# a debugging library is found. +# +# GMOCK_BOTH_LIBRARIES - Both libgmock & libgmock-main +# GMOCK_LIBRARIES - libgmock +# GMOCK_MAIN_LIBRARIES - libgmock-main +# +# Accepts the following variables as input: +# +# GMOCK_ROOT - (as CMake or env. variable) +# The root directory of the gmock install prefix +# +#----------------------- +# Example Usage: +# +# enable_testing(true) +# find_package(GMock REQUIRED) +# include_directories(${GMOCK_INCLUDE_DIRS}) +# +# add_executable(foo foo.cc) +# target_link_libraries(foo ${GMOCK_BOTH_LIBRARIES}) +# +# add_test(AllTestsInFoo foo) +# + +#set (GMOCK_FOUND FALSE) + + +#set (GMOCK_ROOT $ENV{GMOCK_ROOT} CACHE PATH "Path to the gmock root directory.") +if (NOT EXISTS ${GMOCK_ROOT}) + message (FATAL_ERROR "GMOCK_ROOT does not exist.") +endif () + +#set (GMOCK_BUILD ${GMOCK_ROOT}/build CACHE PATH "Path to the gmock build directory.") +if (NOT EXISTS ${GMOCK_BUILD}) + message (FATAL_ERROR "GMOCK_BUILD does not exist.") +endif () + +# Find the include directory +find_path(GMOCK_INCLUDE_DIRS gmock/gmock.h + HINTS + $ENV{GMOCK_ROOT}/include + ${GMOCK_ROOT}/include +) +mark_as_advanced(GMOCK_INCLUDE_DIRS) + +function(_gmock_find_library _name) + find_library(${_name} + NAMES ${ARGN} + HINTS + $ENV{GMOCK_BUILD} + ${GMOCK_BUILD} + ) + mark_as_advanced(${_name}) +endfunction() + +# Find the gmock libraries +if (MSVC) + _gmock_find_library (GMOCK_LIBRARIES_DEBUG gmock ${GMOCK_BUILD}/Debug) + _gmock_find_library (GMOCK_LIBRARIES_RELEASE gmock ${GMOCK_BUILD}/Release) + _gmock_find_library (GMOCK_MAIN_LIBRARIES_DEBUG gmock_main ${GMOCK_BUILD}/Debug) + _gmock_find_library (GMOCK_MAIN_LIBRARIES_RELEASE gmock_main ${GMOCK_BUILD}/Release) + set (GMOCK_LIBRARIES + debug ${GMOCK_LIBRARIES_DEBUG} + optimized ${GMOCK_LIBRARIES_RELEASE} + ) + set (GMOCK_MAIN_LIBRARIES + debug ${GMOCK_MAIN_LIBRARIES_DEBUG} + optimized ${GMOCK_MAIN_LIBRARIES_RELEASE} + ) +else () + _gmock_find_library (GMOCK_LIBRARIES gmock ${GMOCK_BUILD}) + _gmock_find_library (GMOCK_MAIN_LIBRARIES gmock_main ${GMOCK_BUILD} ${GMOCK_BUILD}/Debug) +endif () + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMock DEFAULT_MSG GMOCK_LIBRARIES GMOCK_INCLUDE_DIRS GMOCK_MAIN_LIBRARIES) + +if(GMOCK_FOUND) + set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) + set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES}) +endif() + + From 770f747eec67377eb943b5e7d0eb35da7dd5e29e Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Mon, 20 Aug 2012 00:18:40 +0300 Subject: [PATCH 2/5] Added fix for not visible pthreads functions for linker with glibc 2.15 Signed-off-by: Lukasz Gromanowski --- apps/openmw_test_suite/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt index afe0f30da..cdf8bc74b 100644 --- a/apps/openmw_test_suite/CMakeLists.txt +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -19,6 +19,10 @@ if (GTEST_FOUND AND GMOCK_FOUND) add_executable(openmw_test_suite openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) target_link_libraries(openmw_test_suite ${GMOCK_BOTH_LIBRARIES} ${GTEST_BOTH_LIBRARIES}) + # Fix for not visible pthreads functions for linker with glibc 2.15 + if (UNIX AND NOT APPLE) + target_link_libraries(openmw_test_suite ${CMAKE_THREAD_LIBS_INIT}) + endif() endif() From 65678b95f0e2a0183c874a6e53a37e07ff635ad5 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Wed, 22 Aug 2012 21:11:03 +0300 Subject: [PATCH 3/5] Added support for make install. Added support for make install based on patch from Hasufells repository: https://github.com/hasufell/hasufell-overlay/tree/master/games-engines/openmw/files Signed-off-by: Lukasz Gromanowski --- CMakeLists.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index df05b72e8..cd888df72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -634,3 +634,34 @@ if (APPLE) " COMPONENT Runtime) include(CPack) endif (APPLE) + +## Linux building +# paths +set(BINDIR "${CMAKE_INSTALL_PREFIX}/usr/bin" CACHE PATH "Where to install binaries") +set(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location") +set(DATADIR "${DATAROOTDIR}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location") +set(DOCDIR "${DATAROOTDIR}/doc/openmw" CACHE PATH "Sets the doc directory to a non-default location.") +set(MANDIR "${DATAROOTDIR}/man" CACHE PATH "Where to install manpages") +set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc/openmw" CACHE PATH "Set config dir") +set(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir") + +# Install binaries +INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" ) +INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" ) +INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) +INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" ) + +# Install icon and .desktop +INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}") +INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications") + +# Install global configuration files +INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" ) +#INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" ) +INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" ) +INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" ) +INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.cfg" DESTINATION "${SYSCONFDIR}" ) + +# Install resources +INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" ) +INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" ) From cd3e780614e4cd595997c8ecc1a5900ecc70ef13 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Sat, 8 Sep 2012 20:34:43 +0200 Subject: [PATCH 4/5] Removing the unnecessary local variables --- components/files/linuxpath.cpp | 10 +++------- components/files/macospath.cpp | 5 +---- components/files/windowspath.cpp | 10 ++-------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index 0746350c8..1716757c6 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -44,7 +44,6 @@ LinuxPath::LinuxPath(const std::string& application_name) boost::filesystem::path LinuxPath::getUserPath() const { boost::filesystem::path userPath("."); - boost::filesystem::path suffix(mName); const char* theDir = getenv("HOME"); if (theDir == NULL) @@ -62,15 +61,12 @@ boost::filesystem::path LinuxPath::getUserPath() const userPath = boost::filesystem::path(theDir); } - userPath /= suffix; - - return userPath; + return userPath / mName; } boost::filesystem::path LinuxPath::getCachePath() const { boost::filesystem::path userPath("."); - boost::filesystem::path suffix(mName); const char* theDir = getenv("HOME"); if (theDir == NULL) @@ -86,9 +82,9 @@ boost::filesystem::path LinuxPath::getCachePath() const { userPath = boost::filesystem::path(theDir); } - userPath /= ".cache" / suffix; + userPath /= ".cache"; - return userPath; + return userPath / mName; } boost::filesystem::path LinuxPath::getGlobalPath() const diff --git a/components/files/macospath.cpp b/components/files/macospath.cpp index d9ebb2e2d..9625612ad 100644 --- a/components/files/macospath.cpp +++ b/components/files/macospath.cpp @@ -47,7 +47,6 @@ MacOsPath::MacOsPath(const std::string& application_name) boost::filesystem::path MacOsPath::getUserPath() const { boost::filesystem::path userPath("."); - boost::filesystem::path suffix(mName); const char* theDir = getenv("HOME"); if (theDir == NULL) @@ -63,9 +62,7 @@ boost::filesystem::path MacOsPath::getUserPath() const userPath = boost::filesystem::path(theDir) / "Library/Preferences/"; } - userPath /= suffix; - - return userPath; + return userPath / mName; } boost::filesystem::path MacOsPath::getGlobalPath() const diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index dffe3410f..e8f1a2b08 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -28,7 +28,6 @@ WindowsPath::WindowsPath(const std::string& application_name) boost::filesystem::path WindowsPath::getUserPath() const { boost::filesystem::path userPath("."); - boost::filesystem::path suffix(mName); TCHAR path[MAX_PATH]; memset(path, 0, sizeof(path)); @@ -39,15 +38,12 @@ boost::filesystem::path WindowsPath::getUserPath() const userPath = boost::filesystem::path(path); } - userPath /= suffix; - - return userPath; + return userPath / mName; } boost::filesystem::path WindowsPath::getGlobalPath() const { boost::filesystem::path globalPath("."); - boost::filesystem::path suffix(mName); TCHAR path[MAX_PATH]; memset(path, 0, sizeof(path)); @@ -57,9 +53,7 @@ boost::filesystem::path WindowsPath::getGlobalPath() const globalPath = boost::filesystem::path(path); } - globalPath /= suffix; - - return globalPath; + return globalPath / mName; } boost::filesystem::path WindowsPath::getLocalPath() const From bc6d87ba324040dcb82392e3f29709351a146d1f Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Sat, 8 Sep 2012 23:04:53 +0200 Subject: [PATCH 5/5] Oops, that would've broken getUserPath() on Linux... --- components/files/linuxpath.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index 1716757c6..0f08b67fe 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -57,11 +57,10 @@ boost::filesystem::path LinuxPath::getUserPath() const if (theDir != NULL) { - suffix = boost::filesystem::path("/.config/"); userPath = boost::filesystem::path(theDir); } - return userPath / mName; + return userPath / ".config" / mName; } boost::filesystem::path LinuxPath::getCachePath() const @@ -82,9 +81,8 @@ boost::filesystem::path LinuxPath::getCachePath() const { userPath = boost::filesystem::path(theDir); } - userPath /= ".cache"; - return userPath / mName; + return userPath / ".cache" / mName; } boost::filesystem::path LinuxPath::getGlobalPath() const