Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions cmake/modules/RootNewMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,67 @@ function(ROOT_ADD_TEST test)

endfunction()

#----------------------------------------------------------------------------
# ROOT_PATH_TO_STRING( <variable> path PATH_SEPARATOR_REPLACEMENT replacement )
#
# Mangle the path to a string.
#----------------------------------------------------------------------------
function(ROOT_PATH_TO_STRING resultvar path)
# FIXME: Copied and modified from ROOTTEST_TARGETNAME_FROM_FILE. We should find a common place for that code.
# FIXME: ROOTTEST_TARGETNAME_FROM_FILE could be replaced by just a call to string(MAKE_C_IDENTIFIER)...
CMAKE_PARSE_ARGUMENTS(ARG "" "" "PATH_SEPARATOR_REPLACEMENT" ${ARGN})

set(sep_replacement "")
if (ARG_PATH_SEPARATOR_REPLACEMENT)
set(sep_replacement ${ARG_PATH_SEPARATOR_REPLACEMENT})
endif()

get_filename_component(realfp ${path} ABSOLUTE)
get_filename_component(filename_we ${path} NAME_WE)

string(REPLACE "${CMAKE_SOURCE_DIR}" "" relativepath ${realfp})
string(REPLACE "${path}" "" relativepath ${relativepath})

string(MAKE_C_IDENTIFIER ${relativepath}${filename_we} mangledname)
string(REPLACE "_" "${sep_replacement}" mangledname ${mangledname})

set(${resultvar} "${mangledname}" PARENT_SCOPE)
endfunction(ROOT_PATH_TO_STRING)

#----------------------------------------------------------------------------
# ROOT_ADD_UNITTEST_SUBDIRECTORY( <name> LIBRARIES)
#----------------------------------------------------------------------------
function(ROOT_ADD_UNITTEST_SUBDIRECTORY subdir)
ROOT_GLOB_FILES(test_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/*.cxx)
# Get the component from the path. Eg. core to form coreTests test suite name.
ROOT_PATH_TO_STRING(test_name ${CMAKE_CURRENT_SOURCE_DIR}/Tests/)
ROOT_ADD_GTEST(${test_name} ${test_files} ${ARGN})
# Override the target output folder for to put the binaries in the ${subdir}.
set_property(TARGET ${test_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${subdir}/)
endfunction()

#----------------------------------------------------------------------------
# function ROOT_ADD_GTEST(<testsuite> source1 source2... LIBRARIES)
#
function(ROOT_ADD_GTEST test_suite)
CMAKE_PARSE_ARGUMENTS(ARG "" "" "LIBRARIES" ${ARGN})
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR})

set(source_files ${ARG_UNPARSED_ARGUMENTS})
# Note we cannot use ROOT_EXECUTABLE without user-specified set of LIBRARIES to link with.
# The test suites should choose this in their specific CMakeLists.txt file.
# FIXME: For better coherence we could restrict the libraries the test suite could link
# against. For example, tests in Core should link only against libCore. This could be tricky
# to implement because some ROOT components create more than one library.
ROOT_EXECUTABLE(${test_suite} ${source_files} LIBRARIES ${ARG_LIBRARIES})
set_property(TARGET ${test_suite} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${test_suite} gtest gtest_main gmock gmock_main)

ROOT_PATH_TO_STRING(mangled_name ${test_suite} PATH_SEPARATOR_REPLACEMENT "-")
ROOT_ADD_TEST(gtest${mangled_name} COMMAND ${test_suite})
endfunction()


#----------------------------------------------------------------------------
# ROOT_ADD_TEST_SUBDIRECTORY( <name> )
#----------------------------------------------------------------------------
Expand Down
64 changes: 64 additions & 0 deletions cmake/modules/SearchInstalledSoftware.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,70 @@ if(tmva AND imt)
find_package(BLAS)
endif()


#---Download googletest--------------------------------------------------------------
if (testing)
# FIXME: Remove our version of gtest in roottest. We can reuse this one.
# Add gtest
# http://stackoverflow.com/questions/9689183/cmake-googletest

set(_byproduct_binary_dir
${CMAKE_CURRENT_BINARY_DIR}/googletest-prefix/src/googletest-build/googlemock/)
set(_byproducts
${_byproduct_binary_dir}/gtest/libgtest.a
${_byproduct_binary_dir}/gtest/libgtest_main.a
${_byproduct_binary_dir}/libgmock.a
${_byproduct_binary_dir}/libgmock_main.a
)
ExternalProject_Add(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.8.0
# TIMEOUT 10
# # Force separate output paths for debug and release builds to allow easy
# # identification of correct lib in subsequent TARGET_LINK_LIBRARIES commands
# CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
# -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
# -Dgtest_force_shared_crt=ON
# Disable install step
INSTALL_COMMAND ""
BUILD_BYPRODUCTS ${_byproducts}
# Wrap download, configure and build steps in a script to log output
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON)

# Specify include dirs for gtest and gmock
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIR ${source_dir}/googletest/include)
set(GMOCK_INCLUDE_DIR ${source_dir}/googlemock/include)

# Libraries
ExternalProject_Get_Property(googletest binary_dir)
set(_G_LIBRARY_PATH ${binary_dir}/googlemock/)

# gtest
add_library(gtest IMPORTED STATIC GLOBAL)
set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/gtest/libgtest.a)
add_dependencies(gtest googletest)

# gtest_main
add_library(gtest_main IMPORTED STATIC GLOBAL)
set_property(TARGET gtest_main PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/gtest/libgtest_main.a)
add_dependencies(gtest_main googletest)

# gmock
add_library(gmock IMPORTED STATIC GLOBAL)
set_property(TARGET gmock PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/libgmock.a)
add_dependencies(gmock googletest)

# gmock_main
add_library(gmock_main IMPORTED STATIC GLOBAL)
set_property(TARGET gmock_main PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/libgmock_main.a)
add_dependencies(gmock_main googletest)

endif()

#---Report non implemented options---------------------------------------------------
foreach(opt afs glite sapdb srp)
if(${opt})
Expand Down
7 changes: 7 additions & 0 deletions core/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
# CMakeLists.txt file for building ROOT core/base package
############################################################################

if(testing)
# FIXME: The tests in core should require only libCore. OTOH, TQObjectTests uses the interpreter to register the class.
# This means that if we run make CoreBaseTests the executable wouldn't be runnable because it requires libCling and
# onepcm targets to be built.
ROOT_ADD_UNITTEST_SUBDIRECTORY(test LIBRARIES Core Cling RIO)
endif()

ROOT_GLOB_HEADERS(Base_dict_headers ${CMAKE_CURRENT_SOURCE_DIR}/inc/T*.h
${CMAKE_CURRENT_SOURCE_DIR}/inc/GuiTypes.h
${CMAKE_CURRENT_SOURCE_DIR}/inc/KeySymbols.h
Expand Down
11 changes: 11 additions & 0 deletions core/base/test/TNamedTests.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "TNamed.h"

TEST(TNamed, Sanity)
{
TNamed n("Name", "Title");
EXPECT_STREQ("Name", n.GetName());
EXPECT_STREQ("Title", n.GetTitle());
}
47 changes: 47 additions & 0 deletions core/base/test/TQObjectTests.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "Rtypes.h"
#include "TQObject.h"
#include "TQConnection.h"

#include "RQ_OBJECT.h"

#define Stringify(s) Stringifyx(s)
#define Stringifyx(s) #s

// The interpreter needs to know about RQ_OBJECTTester and using this trick avoids moving this non-reusable class into
// its own header file.
#define DICT_CLASS \
class RQ_OBJECTTester : public TQObject { \
/* This will expand, adding signal/slot support to this class */ \
RQ_OBJECT("RQ_OBJECTTester"); \
Int_t fValue = 0; \
\
public: \
void SetValue(Int_t value) \
{ \
/* to prevent infinite looping in the case of cyclic connections */ \
if (value != fValue) { \
fValue = value; \
Emit("SetValue(Int_t)", fValue); \
} \
} \
void PrintValue() const { printf("value=%d\n", fValue); } \
Int_t GetValue() const { return fValue; } \
};

DICT_CLASS;

TEST(TQObject, Emit)
{
gInterpreter->ProcessLine(Stringify(DICT_CLASS));
RQ_OBJECTTester a;
RQ_OBJECTTester b;
a.Connect("SetValue(Int_t)", "RQ_OBJECTTester", &b, "SetValue(Int_t)");

EXPECT_EQ(0, b.GetValue());

a.SetValue(1);
EXPECT_EQ(1, b.GetValue());
}