cmake_minimum_required(VERSION 3.16)

project(%{TestCaseName} LANGUAGES CXX)

enable_testing()

@if "%{TestFrameWork}" == "QtTest"
@if "%{RequireGUI}" == "true"
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui Test)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Test)
@else
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Test)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test)
@endif

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})

@if "%{RequireGUI}" == "true"
target_link_libraries(%{TestCaseName} PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Test)
@else
target_link_libraries(%{TestCaseName} PRIVATE Qt${QT_VERSION_MAJOR}::Test)
@endif

@endif
@if "%{TestFrameWork}" == "QtQuickTest"
@if "%{UseSetupCode}" === "true"
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTest Qml)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS QuickTest Qml)
@else
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTest)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS QuickTest)
@endif

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# no need to copy around qml test files for shadow builds - just set the respective define
add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")

add_custom_target(%{TestCaseName}_qmlfiles SOURCES %{TestCaseFileWithQmlSuffix})

@if "%{UseSetupCode}" === "true"
add_executable(%{TestCaseName} %{MainCppName}
               setup.cpp setup.h)
@else
add_executable(%{TestCaseName} %{MainCppName})
@endif
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})

@if "%{UseSetupCode}" === "true"
target_link_libraries(%{TestCaseName}
                      PRIVATE Qt${QT_VERSION_MAJOR}::QuickTest
                      PRIVATE Qt${QT_VERSION_MAJOR}::Qml)
@else
target_link_libraries(%{TestCaseName} PRIVATE Qt${QT_VERSION_MAJOR}::QuickTest)
@endif

@endif
@if  "%{TestFrameWork}" == "GTest"
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if ($ENV{GOOGLETEST_DIR})
    get_filename_component(_GTEST_BASE $ENV{GOOGLETEST_DIR} REALPATH)
elseif (EXISTS "%{GTestBaseFolder}") # set by QC
    get_filename_component(_GTEST_BASE "%{GTestBaseFolder}" REALPATH) # set by QC
elseif (UNIX AND EXISTS "/usr/src/gtest")
    set(_GTEST_BASE "/usr/src/gtest")
endif()

if (_GTEST_BASE AND NOT EXISTS "${_GTEST_BASE}/googletest/src/gtest-all.cc"
        OR NOT EXISTS "${_GTEST_BASE}/googlemock/src/gmock-all.cc")
    message(ERROR "Missing source components (gtest-all.cc and/or gmock-all.cc).")
endif()

find_package(Threads REQUIRED)

include_directories(
    ${_GTEST_BASE}/googletest ${_GTEST_BASE}/googletest/include
    ${_GTEST_BASE}/googlemock ${_GTEST_BASE}/googlemock/include
)
add_executable(%{TestCaseName} %{MainCppName} %{TestCaseFileGTestWithCppSuffix}
               ${_GTEST_BASE}/googletest/src/gtest-all.cc
               ${_GTEST_BASE}/googlemock/src/gmock-all.cc
           )

add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})
target_link_libraries(%{TestCaseName} PRIVATE Threads::Threads)
@endif
@if "%{TestFrameWork}" == "GTest_dyn"
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if ($ENV{GOOGLETEST_DIR})
    get_filename_component(_GTEST_BASE $ENV{GOOGLETEST_DIR} REALPATH)
elseif (EXISTS "%{GTestBaseFolder}") # set by QC
    get_filename_component(_GTEST_BASE "%{GTestBaseFolder}" REALPATH) # set by QC
endif()

if (NOT GTEST_ROOT)
    if (_GTEST_BASE)
        message("Setting GTEST_ROOT to ${_GTEST_BASE}")
        set(GTEST_ROOT ${_GTEST_BASE})
    else()
        message("No GTEST_ROOT specified - using system defaults.")
    endif()
endif()

find_package(GTest REQUIRED)
if (NOT GTest_FOUND)
    message (FATAL_ERROR "No GTest Found")
endif()

add_executable(%{TestCaseName} %{MainCppName} %{TestCaseFileGTestWithCppSuffix})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})

target_link_libraries(%{TestCaseName} PRIVATE GTest::GTest)
if (GMock_FOUND)
    target_link_libraries(%{TestCaseName} INTERFACE GTest::GMock)
endif()
@endif
@if "%{TestFrameWork}" == "BoostTest"
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(%{TestCaseName} %{MainCppName})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})

if (DEFINED ENV{BOOST_INCLUDE_DIR})
    set(BOOST_INCLUDE_DIR $ENV{BOOST_INCLUDE_DIR})
else ()
    set(BOOST_INCLUDE_DIR "%{BoostIncDir}") # set by Qt Creator wizard
endif ()
if (BOOST_INCLUDE_DIR STREQUAL "")
    message("BOOST_INCLUDE_DIR is not set, assuming Boost can be found automatically in your system")
elseif (EXISTS ${BOOST_INCLUDE_DIR})
    include_directories(${BOOST_INCLUDE_DIR})
endif ()
@endif
@if "%{TestFrameWork}" == "BoostTest_dyn"
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

if (DEFINED ENV{BOOST_INSTALL_DIR})
    set(BOOST_INSTALL_DIR $ENV{BOOST_INSTALL_DIR})
else ()
    set(BOOST_INSTALL_DIR "%{BoostInstallDir}") # set by Qt Creator wizard
endif ()
if (BOOST_INSTALL_DIR STREQUAL "")
    message("BOOST_INSTALL_DIR not set, assuming Boost can be found automatically in your system")
elseif (EXISTS ${BOOST_INSTALL_DIR})
    set(BOOST_ROOT ${BOOST_INSTALL_DIR})
endif ()
find_package(Boost COMPONENTS unit_test_framework REQUIRED)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(%{TestCaseName} %{MainCppName} %{TestCaseFileWithCppSuffix})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})
if (Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
  target_link_libraries(%{TestCaseName} PUBLIC ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
endif ()
@endif
@if "%{TestFrameWork}" == "Catch2"
SET(CMAKE_CXX_STANDARD 11)

@if "%{Catch2NeedsQt}" == "true"
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui)
@endif

add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix} %{MainCppName})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})

@if "%{Catch2NeedsQt}" == "true"
target_link_libraries(%{TestCaseName} PRIVATE Qt${QT_VERSION_MAJOR}::Gui)
@endif

if (DEFINED ENV{CATCH_INCLUDE_DIR})
    set(CATCH_INCLUDE_DIR $ENV{CATCH_INCLUDE_DIR})
else ()
    set(CATCH_INCLUDE_DIR "%{CatchIncDir}") # set by Qt Creator wizard
endif ()
if (CATCH_INCLUDE_DIR STREQUAL "")
    message("CATCH_INCLUDE_DIR is not set, assuming Catch2 can be found automatically in your system")
elseif (EXISTS ${CATCH_INCLUDE_DIR})
    include_directories(${CATCH_INCLUDE_DIR})
endif ()
@endif
@if "%{TestFrameWork}" == "Catch2_dyn"
SET(CMAKE_CXX_STANDARD 11)

if ($ENV{CATCH2_INSTALL_DIR})
    get_filename_component(_CATCH2_BASE $ENV{CATCH2_INSTALL_DIR} REALPATH)
elseif (EXISTS "%{CatchInstallDir}") # set by QC
    get_filename_component(_CATCH2_BASE "%{CatchInstallDir}" REALPATH) # set by QC
endif()

if (NOT Catch2_DIR)
    if (_CATCH2_BASE)
        if (EXISTS "${_CATCH2_BASE}/lib/cmake/Catch2")
            set(_CATCH2_BASE "${_CATCH2_BASE}/lib/cmake/Catch2")
        endif()
        message("Setting Catch2_DIR to ${_CATCH2_BASE}")
        set(Catch2_DIR ${_CATCH2_BASE})
    else()
        message("No Catch2_DIR specified - using system defaults.")
    endif()
endif()

find_package(Catch2 3 REQUIRED)
@if "%{Catch2NeedsQt}" == "true"
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui)
@endif

@if "%{Catch2Main}" == "false"
add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix})
target_link_libraries(%{TestCaseName} PRIVATE Catch2::Catch2WithMain)
@else
add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix} %{MainCppName})
target_link_libraries(%{TestCaseName} PRIVATE Catch2::Catch2)
@endif
@if "%{Catch2NeedsQt}" == "true"
target_link_libraries(%{TestCaseName} PRIVATE Qt${QT_VERSION_MAJOR}::Gui)
@endif

add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})
@endif

include(GNUInstallDirs)
install(TARGETS %{TestCaseName}
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
