From d97ab5c70988816b42201479d3fcf75ce0c33e8c Mon Sep 17 00:00:00 2001
From: Tomas Pecka <peckato1@fit.cvut.cz>
Date: Thu, 21 Feb 2019 11:24:44 +0100
Subject: [PATCH] CMake: support for integration tests with Catch

---
 CMake/CMakeLists_itest.txt | 43 ++++++++++++++++++++++++++++++++++++++
 CMake/CMakeLists_root.txt  | 15 +++++--------
 CMake/generate.conf        |  1 +
 CMake/generate.py          | 17 ++++++++++++++-
 CMake/testfiles.hpp.in     |  6 ++++++
 5 files changed, 71 insertions(+), 11 deletions(-)
 create mode 100644 CMake/CMakeLists_itest.txt
 create mode 100644 CMake/testfiles.hpp.in

diff --git a/CMake/CMakeLists_itest.txt b/CMake/CMakeLists_itest.txt
new file mode 100644
index 0000000000..ae311993d4
--- /dev/null
+++ b/CMake/CMakeLists_itest.txt
@@ -0,0 +1,43 @@
+find_package(Catch2 REQUIRED)
+include(Catch)
+
+project({project_name})
+set(PROJECT_NAME_TEST test-{project_name})
+
+{cmake_options}
+{find_packages_tests}
+
+set(SOURCE_FILES_TEST
+        {source_files_test}
+        )
+
+set( TEST_FILES_BASEDIR ${{CMAKE_SOURCE_DIR}}/examples2 )
+configure_file (
+    ${{CMAKE_SOURCE_DIR}}/CMake/testfiles.hpp.in
+    ${{CMAKE_BINARY_DIR}}/generated/testfiles_basedir.hpp
+)
+
+add_executable(${{PROJECT_NAME_TEST}} ${{SOURCE_FILES_TEST}})
+set_target_properties(${{PROJECT_NAME_TEST}} PROPERTIES
+        CXX_STANDARD 17
+        CXX_STANDARD_REQUIRED ON
+        )
+
+target_link_libraries(${{PROJECT_NAME_TEST}} {target_test_libs} Catch2::Catch2)
+
+# Include dependencies directories
+target_include_directories(${{PROJECT_NAME_TEST}}
+        PUBLIC ${{CMAKE_CURRENT_SOURCE_DIR}}/test-src # anything that depends on this should include src also, hence public
+        ${{CMAKE_BINARY_DIR}}/generated # testfiles header
+        {include_test_paths}
+        )
+
+# if (CMAKE_BUILD_TYPE STREQUAL "Release")
+#         set_property ( TARGET ${{PROJECT_NAME_TEST}} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE )
+# endif ()
+
+catch_discover_tests(
+	${{PROJECT_NAME_TEST}}
+	TEST_SPEC "[integration]"
+	TEST_PREFIX "[integration] "
+)
diff --git a/CMake/CMakeLists_root.txt b/CMake/CMakeLists_root.txt
index 07d8e1b42a..f63601c8a0 100644
--- a/CMake/CMakeLists_root.txt
+++ b/CMake/CMakeLists_root.txt
@@ -91,6 +91,10 @@ set(ALIB_MODULES_LIB
 set(ALIB_MODULES_EXE
         {alib_modules_exe}
         )
+set(ALIB_MODULES_TEST
+        {alib_modules_test}
+        )
+
 
 ##################
 # configure version
@@ -105,15 +109,6 @@ add_subdirectory ( contrib/catch2 )
 
 ##################
 # Register modules
-foreach (module ${{ALIB_MODULES_LIB}} ${{ALIB_MODULES_EXE}})
+foreach (module ${{ALIB_MODULES_LIB}} ${{ALIB_MODULES_EXE}} ${{ALIB_MODULES_TEST}})
     add_subdirectory(${{module}})
 endforeach ()
-
-#######
-# Tests
-#  - enable
-enable_testing()
-# include(CTest) # we do not need full CTest support now
-
-# register bash tests
-# TODO
diff --git a/CMake/generate.conf b/CMake/generate.conf
index f6582191cb..0ff8fe2b8a 100644
--- a/CMake/generate.conf
+++ b/CMake/generate.conf
@@ -18,6 +18,7 @@ gui
 root:       CMakeLists_root.txt
 executable: CMakeLists_bin.txt
 library:    CMakeLists_lib.txt
+testing:    CMakeLists_itest.txt
 
 [CMake:Sources]
 ; where to find sources, relative to {PROJECT_DIR}
diff --git a/CMake/generate.py b/CMake/generate.py
index 23ed8f1cd9..b1b941ef28 100755
--- a/CMake/generate.py
+++ b/CMake/generate.py
@@ -205,6 +205,7 @@ class Generator:
             f.write(CATEGORIES['root'].format(
                 alib_modules_lib=Helpers.join([p.name for p in projects if p.category == "library"]),
                 alib_modules_exe=Helpers.join([p.name for p in projects if p.category == "executable"]),
+                alib_modules_test=Helpers.join([p.name for p in projects if p.category == "testing"]),
                 alib_versioning_major=Config.get(CONFIG, 'Versioning', 'major'),
                 alib_versioning_minor=Config.get(CONFIG, 'Versioning', 'minor'),
                 alib_versioning_patch=Config.get(CONFIG, 'Versioning', 'patch'),
@@ -230,6 +231,20 @@ class Generator:
                 find_packages_tests=Helpers.join(map(lambda p: "find_package({})".format(p), test_finds), "\n"),
             ))
 
+    @classmethod
+    def generate_testing(cls, project, dry_run):
+        test_sys_includes, test_sys_libs, test_finds = cls._handle_system_deps(project, project.system_deps_test)
+
+        with SmartOpen("CMakeLists.txt", 'w', directory=project.path, dry_run=dry_run) as f:
+            f.write(CATEGORIES[project.category].format(
+                project_name=project.name,
+                target_test_libs=Helpers.join(project.dependencies_test + test_sys_libs, ' '),
+                include_test_paths=Helpers.join(test_sys_includes, ' '),
+                cmake_options=Helpers.join(["set({} {})".format(k.upper(), v) for k, v in project.cmake_additional_set], sep='\n'),
+                source_files_test=Helpers.join(project.find_sources_test()),
+                find_packages_tests=Helpers.join(map(lambda p: "find_package({})".format(p), test_finds), "\n"),
+            ))
+
     @classmethod
     def generate_executable(cls, project, dry_run):
         sys_includes, sys_libs, finds = cls._handle_system_deps(project, project.system_deps)
@@ -376,7 +391,7 @@ if __name__ == '__main__':
 
     if args.version is True:
         print("{}.{}.{}".format(Config.get(CONFIG, 'Versioning', 'major'),
-                Config.get(CONFIG, 'Versioning', 'minor'),
+            Config.get(CONFIG, 'Versioning', 'minor'),
 	        Config.get(CONFIG, 'Versioning', 'patch')))
         sys.exit(0)
 
diff --git a/CMake/testfiles.hpp.in b/CMake/testfiles.hpp.in
new file mode 100644
index 0000000000..7fde86fefc
--- /dev/null
+++ b/CMake/testfiles.hpp.in
@@ -0,0 +1,6 @@
+#ifndef __TEST_FILES_HPP_
+#define __TEST_FILES_HPP_
+
+#define TEST_FILES_BASEDIR "${TEST_FILES_BASEDIR}"
+
+#endif /* __TEST_FILES_HPP_ */
-- 
GitLab