diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cc28cfef900daa32b8218a4aa0c42edda324f4a..0c2c15567a7a6f0b6e26c7fb4b7bea9b2b0a4f92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,16 @@ message(STATUS "Configured to compile in ${CMAKE_BUILD_TYPE} mode.") SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT") SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -D_REENTRANT") +#Build tests +IF(NOT BUILD_TESTS) + OPTION(BUILD_TESTS "Build Unit tests" ON) +ENDIF(NOT BUILD_TESTS) + +#Build demos +IF(NOT BUILD_DEMOS) + OPTION(BUILD_DEMOS "Build demos" ON) +ENDIF(NOT BUILD_DEMOS) + #Set compiler according C++11 support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) @@ -40,9 +50,20 @@ else() message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() - ADD_SUBDIRECTORY(src) +#Build tests +IF(BUILD_TESTS) + # Enables testing for this directory and below. + # Note that ctest expects to find a test file in the build directory root. + # Therefore, this command should be in the source directory root. + #include(CTest) # according to http://public.kitware.com/pipermail/cmake/2012-June/050853.html + MESSAGE("Building tests.") + enable_testing() + set(_LASER_SCAN_UTILS_ROOT_DIR ${CMAKE_SOURCE_DIR}) + add_subdirectory(test) +ENDIF(BUILD_TESTS) + FIND_PACKAGE(Doxygen) FIND_PATH(IRI_DOC_DIR doxygen.conf ${CMAKE_SOURCE_DIR}/doc/iri_doc/) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d787d5dfff365c3dea62442e89764caea5246ea7..5a9977bbaa8efa7dc7562350ae99b61200b54f8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,15 +15,10 @@ FIND_PACKAGE(csm QUIET) #include directories INCLUDE_DIRECTORIES(. /usr/local/include) -IF(Eigen3_FOUND) - INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) -ENDIF(Eigen3_FOUND) +INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) IF(csm_FOUND) INCLUDE_DIRECTORIES(${csm_INCLUDE_DIR}) ENDIF(csm_FOUND) -IF(Ceres_FOUND) - INCLUDE_DIRECTORIES(${CERES_INCLUDE_DIRS}) -ENDIF(Ceres_FOUND) IF(faramotics_FOUND) INCLUDE_DIRECTORIES(${faramotics_INCLUDE_DIRS}) ENDIF(faramotics_FOUND) @@ -76,12 +71,19 @@ SET(SRCS SET(SRCS ${SRCS} icp.cpp) ENDIF(csm_FOUND) + # create the shared library ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) IF(csm_FOUND) target_link_libraries(${PROJECT_NAME} ${csm_LIBRARY}) ENDIF(csm_FOUND) +# Examples +IF(BUILD_DEMOS) + MESSAGE("Building examples.") + ADD_SUBDIRECTORY(examples) +ENDIF(BUILD_DEMOS) + #install library INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin @@ -96,13 +98,3 @@ INSTALL(FILES ${HDRS} #install Find*.cmake INSTALL(FILES ../Findlaser_scan_utils.cmake DESTINATION ${CMAKE_ROOT}/Modules/) - -#Build examples & tests -IF(NOT BUILD_TESTS) - OPTION(BUILD_TESTS "Build Unit tests" ON) -ENDIF(NOT BUILD_TESTS) - -IF(BUILD_TESTS) - MESSAGE("Building tests.") - ADD_SUBDIRECTORY(test) -ENDIF(BUILD_TESTS) diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..005644f61512355f277bb90bb567f45a8acf60d1 --- /dev/null +++ b/src/examples/CMakeLists.txt @@ -0,0 +1,5 @@ +INCLUDE_DIRECTORIES(../src) + +# polylines demo +ADD_EXECUTABLE(demo_polylines polyline_demo.cpp) +TARGET_LINK_LIBRARIES(demo_polylines ${PROJECT_NAME}) \ No newline at end of file diff --git a/src/test/polyline_test.cpp b/src/examples/polyline_demo.cpp similarity index 99% rename from src/test/polyline_test.cpp rename to src/examples/polyline_demo.cpp index 8c50bdfe99653a6ee55982f33fee0d90ed473367..47bf725adf11f113ee96c21b07cec70e1125f7ca 100644 --- a/src/test/polyline_test.cpp +++ b/src/examples/polyline_demo.cpp @@ -6,8 +6,8 @@ */ //LaserScanUtils includes -#include "../line_finder_iterative.h" -#include "../laser_scan.h" +#include "line_finder_iterative.h" +#include "laser_scan.h" //std includes #include <ctime> diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt deleted file mode 100644 index 70c90f613a07cd22b2c39d393b5ff469157190cc..0000000000000000000000000000000000000000 --- a/src/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# polylines test -ADD_EXECUTABLE(test_polylines polyline_test.cpp) -TARGET_LINK_LIBRARIES(test_polylines ${PROJECT_NAME}) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6cd8581ea6483c152ff1562ce6670a2066448522 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,17 @@ +# Retrieve googletest from github & compile +add_subdirectory(gtest) + +# Include gtest directory. +include_directories(${GTEST_INCLUDE_DIRS}) + +############# USE THIS TEST AS AN EXAMPLE #################### +# # +# Create a specific test executable for gtest_example # +# gnss_utils_add_gtest(gtest_example gtest_example.cpp) # +# target_link_libraries(gtest_example ${PROJECT_NAME}) # +# # +############################################################## + +# gtest example +gnss_utils_add_gtest(gtest_example gtest_example.cpp) +target_link_libraries(gtest_example ${PROJECT_NAME}) \ No newline at end of file diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3c3c48c74516488a8c4eb24c2492bd81a5edc7f9 --- /dev/null +++ b/test/gtest/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 2.8.8) +project(gtest_builder C CXX) + +# We need thread support +#find_package(Threads REQUIRED) + +# Enable ExternalProject CMake module +include(ExternalProject) + +set(GTEST_FORCE_SHARED_CRT ON) +set(GTEST_DISABLE_PTHREADS OFF) + +# For some reason I need to disable PTHREADS +# with g++ (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3 +# This is a known issue for MinGW : +# https://github.com/google/shaderc/pull/174 +#if(MINGW) + set(GTEST_DISABLE_PTHREADS ON) +#endif() + +# Download GoogleTest +ExternalProject_Add(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.8.x + # TIMEOUT 1 # We'll try this + CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs + -DCMAKE_CXX_FLAGS=${MSVC_COMPILER_DEFS} + -Dgtest_force_shared_crt=${GTEST_FORCE_SHARED_CRT} + -Dgtest_disable_pthreads=${GTEST_DISABLE_PTHREADS} + -DBUILD_GTEST=ON + PREFIX "${CMAKE_CURRENT_BINARY_DIR}" + # Disable install step + INSTALL_COMMAND "" + UPDATE_DISCONNECTED 1 # 1: do not update googletest; 0: update googletest via github +) + +# Get GTest source and binary directories from CMake project + +# Specify include dir +ExternalProject_Get_Property(googletest source_dir) +set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include PARENT_SCOPE) + +# Specify MainTest's link libraries +ExternalProject_Get_Property(googletest binary_dir) +set(GTEST_LIBS_DIR ${binary_dir}/googlemock/gtest PARENT_SCOPE) + +# Create a libgtest target to be used as a dependency by test programs +add_library(libgtest IMPORTED STATIC GLOBAL) +add_dependencies(libgtest googletest) + +# Set libgtest properties +set_target_properties(libgtest PROPERTIES + "IMPORTED_LOCATION" "${binary_dir}/googlemock/gtest/libgtest.a" + "IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}" +) + +function(gnss_utils_add_gtest target) + add_executable(${target} ${ARGN}) + add_dependencies(${target} libgtest) + target_link_libraries(${target} libgtest) + + #WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + add_test(NAME ${target} COMMAND ${target}) +endfunction() diff --git a/test/gtest/utils_gtest.h b/test/gtest/utils_gtest.h new file mode 100644 index 0000000000000000000000000000000000000000..2deddcb17755bb065887f55ce95ec6be4c8711e4 --- /dev/null +++ b/test/gtest/utils_gtest.h @@ -0,0 +1,146 @@ +/** + * \file utils_gtest.h + * \brief Some utils for gtest + * \author Jeremie Deray + * Created on: 26/09/2016 + * Eigen macros extension by: Joan Sola on 26/04/2017 + */ + +#ifndef GNSSUTILS_UTILS_GTEST_H +#define GNSSUTILS_UTILS_GTEST_H + +#include <gtest/gtest.h> + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// C String Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); +// +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); + +// http://stackoverflow.com/a/29155677 + +namespace testing +{ +namespace internal +{ +enum GTestColor +{ + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +extern void ColoredPrintf(GTestColor color, const char* fmt, ...); + +#define PRINTF(...) \ + do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN,\ + "[ ] "); \ + testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } \ + while(0) + +#define PRINT_TEST_FINISHED \ +{ \ + const ::testing::TestInfo* const test_info = \ + ::testing::UnitTest::GetInstance()->current_test_info(); \ + PRINTF(std::string("Finished test case ").append(test_info->test_case_name()).\ + append(" of test ").append(test_info->name()).append(".\n").c_str()); \ +} + +// C++ stream interface +class TestCout : public std::stringstream +{ +public: + ~TestCout() override + { + PRINTF("%s\n", str().c_str()); + } +}; + +/* Usage : + +TEST(Test, Foo) +{ + // the following works but prints default stream + EXPECT_TRUE(false) << "Testing Stream."; + + // or you can play with AINSI color code + EXPECT_TRUE(false) << "\033[1;31m" << "Testing Stream."; + + // or use the above defined macros + + PRINTF("Hello world"); + + // or + + TEST_COUT << "Hello world"; +} + +*/ +#define TEST_COUT testing::internal::TestCout() + +} // namespace internal + +/* Macros related to testing Eigen classes: + */ +#define EXPECT_MATRIX_APPROX(C_expect, C_actual, precision) EXPECT_PRED2([](const Eigen::MatrixXd lhs, const Eigen::MatrixXd rhs) { \ + return (lhs - rhs).isMuchSmallerThan(1, precision); \ + }, \ + C_expect, C_actual); + +#define ASSERT_MATRIX_APPROX(C_expect, C_actual, precision) ASSERT_PRED2([](const Eigen::MatrixXd lhs, const Eigen::MatrixXd rhs) { \ + return (lhs - rhs).isMuchSmallerThan(1, precision); \ + }, \ + C_expect, C_actual); + +#define EXPECT_QUATERNION_APPROX(C_expect, C_actual, precision) EXPECT_MATRIX_APPROX((C_expect).coeffs(), (C_actual).coeffs(), precision) + +#define ASSERT_QUATERNION_APPROX(C_expect, C_actual, precision) ASSERT_MATRIX_APPROX((C_expect).coeffs(), (C_actual).coeffs(), precision) + +#define EXPECT_POSE2D_APPROX(C_expect, C_actual, precision) EXPECT_PRED2([](const Eigen::MatrixXd lhs, const Eigen::MatrixXd rhs) { \ + MatrixXd er = lhs - rhs; \ + er(2) = pi2pi((double)er(2)); \ + return er.isMuchSmallerThan(1, precision); \ + }, \ + C_expect, C_actual); + +#define ASSERT_POSE2D_APPROX(C_expect, C_actual, precision) EXPECT_PRED2([](const Eigen::MatrixXd lhs, const Eigen::MatrixXd rhs) { \ + MatrixXd er = lhs - rhs; \ + er(2) = pi2pi((double)er(2)); \ + return er.isMuchSmallerThan(1, precision); \ + }, \ + C_expect, C_actual); + +} // namespace testing + +#endif /* GNSSUTILS_UTILS_GTEST_H */ diff --git a/test/gtest_example.cpp b/test/gtest_example.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7dd3b9ceea4ff0b3c7ea1c6f8db3286b273f7b66 --- /dev/null +++ b/test/gtest_example.cpp @@ -0,0 +1,20 @@ +#include "gtest/utils_gtest.h" + +TEST(TestTest, DummyTestExample) +{ + EXPECT_FALSE(false); + + ASSERT_TRUE(true); + + int my_int = 5; + + ASSERT_EQ(my_int, 5); + +// PRINTF("All good at TestTest::DummyTestExample !\n"); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}