AutoTest: Improve Catch2 wizard

Since version 3 of Catch2 it is recommended to use the
approach to link against Catch2 instead of using a single
include.
Make both variants work. There is still a third variant of
using a single include for version 3, which is left out
here, but can easily be fixed for Catch2 users.

Change-Id: I2c25837cb1df4b460b662466dde68563fa7d713c
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Christian Stenger
2023-10-16 12:39:23 +02:00
parent bded214791
commit 67ad0cf556
8 changed files with 214 additions and 11 deletions

View File

@@ -8,14 +8,10 @@
"trDisplayCategory": "Test Project",
"icon": "../autotest.png",
"iconKind": "Themed",
"featuresRequired": [ "QtSupport.Wizards.FeatureDesktop" ],
"enabled": "%{JS: value('Plugins').indexOf('CppEditor') >= 0}",
"options":
[
{ "key": "TestFrameWork",
"value": "Catch2"
},
{ "key": "ProjectFilePath",
"value": "%{JS: value('BuildSystem') == 'qmake' ? value('ProFileName') : (value('BuildSystem') == 'qbs' ? value('QbsFileName') : value('CMakeFileName')) }"
},
@@ -63,6 +59,26 @@
"typeId": "Fields",
"data":
[
{
"name": "TestFrameWork",
"trDisplayName": "Test framework:",
"type": "ComboBox",
"data":
{
"index": 1,
"items":
[
{
"trKey": "Catch2 v2 (header only)",
"value": "Catch2"
},
{
"trKey": "Catch2 v3 (shared libraries)",
"value": "Catch2_dyn"
}
]
}
},
{
"name": "TestCaseName",
"trDisplayName": "Test case name:",
@@ -80,10 +96,28 @@
"kind": "existingDirectory"
}
},
{
"name": "CatchInstallDir",
"trDisplayName": "Catch2 install directory (optional):",
"visible": "%{JS: value('TestFrameWork') === 'Catch2_dyn'}",
"mandatory": false,
"type": "PathChooser",
"data": {
"kind": "existingDirectory"
}
},
{
"name": "Catch2Main",
"trDisplayName": "Use own main",
"visible": "%{JS: '%{TestFrameWork}' === 'Catch2_dyn'}",
"type": "CheckBox",
"data": {
"checked": false
}
},
{
"name": "Catch2NeedsQt",
"trDisplayName": "Use Qt libraries",
"visible": "%{JS: '%{TestFrameWork}' === 'Catch2'}",
"type": "CheckBox",
"data": {
"checked": false
@@ -126,7 +160,7 @@
"enabled": "%{IsTopLevelProject}",
"data": {
"projectFilePath": "%{ProjectFilePath}",
"requiredFeatures": [ "%{JS: (value('Catch2NeedsQt') || value('BuildSystem') === 'qmake') ? 'QtSupport.Wizards.FeatureQt' : 'QtSupport.Wizards.FeatureDesktop' }" ]
"requiredFeatures": [ "%{JS: (value('Catch2NeedsQt') == 'true' || value('BuildSystem') === 'qmake') ? 'QtSupport.Wizards.FeatureQt' : 'DeviceType.Desktop' }" ]
}
},
{
@@ -148,6 +182,12 @@
"openInEditor": false,
"openAsProject": true
},
{
"source": "../files/catch-common.pri",
"target": "catch-common.pri",
"openInEditor": false,
"condition": "%{JS: value('BuildSystem') == 'qmake' && '%{TestFrameWork}' == 'Catch2_dyn'}"
},
{
"source": "../files/tst.qbs",
"target": "%{ProjectFilePath}",
@@ -155,6 +195,12 @@
"openInEditor": false,
"openAsProject": true
},
{
"source": "../files/catchCommon.js",
"target": "catchCommon.js",
"condition": "%{JS: value('BuildSystem') == 'qbs'}",
"openInEditor": false
},
{
"source": "../files/tst.txt",
"target": "CMakeLists.txt",
@@ -164,13 +210,13 @@
},
{
"source": "../files/tst_main.cpp",
"condition": "%{JS: '%{TestFrameWork}' == 'Catch2' || value('Catch2Main') == 'true'}",
"target": "%{MainCppName}",
"openInEditor": true
},
{
"source": "../files/catch2_tst.cpp",
"target": "%{TestCaseFileWithCppSuffix}",
"condition": "%{JS: '%{TestFrameWork}' === 'Catch2'}",
"openInEditor": true
},
{

View File

@@ -0,0 +1,21 @@
isEmpty(CATCH2_INSTALL_DIR):CATCH2_INSTALL_DIR=$$(CATCH2_INSTALL_DIR)
isEmpty(CATCH2_INSTALL_DIR) {
CATCH2_INSTALL_DIR = "%{CatchInstallDir}" # set by QC
!isEmpty(CATCH2_INSTALL_DIR) {
warning("Using Catch2 installation specified at Qt Creator wizard.")
message("Set CATCH2_INSTALL_DIR as environment variable or qmake variable to get rid of this message")
} else {
message("Using Catch2 from system - set CATCH2_INSTALL_DIR is it cannot be found automatically.")
}
}
!isEmpty(CATCH2_INSTALL_DIR): {
INCLUDEPATH *= "$$CATCH2_INSTALL_DIR/include"
equals(CATCH2_MAIN, 0): LIBS *= -L"$$CATCH2_INSTALL_DIR/lib" -lCatch2Main -lCatch2
else: LIBS *= -L"$$CATCH2_INSTALL_DIR/lib" -lCatch2
} else {
equals(CATCH2_MAIN, 0): LIBS *= -lCatch2Main -lCatch2
else: LIBS *= -lCatch2
}

View File

@@ -1,4 +1,8 @@
@if "%{TestFrameWork}" == "Catch2"
#include <catch2/catch.hpp>
@else
#include <catch2/catch_test_macros.hpp>
@endif
TEST_CASE("My first test with Catch2", "[fancy]")
{

View File

@@ -0,0 +1,16 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
var File = require("qbs.File")
var FileInfo = require("qbs.FileInfo")
function getChildPath(qbs, baseFolder, childFolder)
{
if (!baseFolder)
return [];
var childPath = FileInfo.joinPaths(baseFolder, childFolder);
if (File.exists(childPath))
return [childPath];
return [];
}

View File

@@ -95,7 +95,7 @@ SOURCES += \\
%{MainCppName} \\
%{TestCaseFileWithCppSuffix}
@endif
@if "%{TestFrameWork}" == "Catch2"
@if "%{TestFrameWork}" == "Catch2" || "%{TestFrameWork}" == "Catch2_dyn"
TEMPLATE = app
@if "%{Catch2NeedsQt}" == "true"
QT += gui
@@ -106,7 +106,8 @@ CONFIG += console
@endif
CONFIG += c++11
@endif
@if "%{TestFrameWork}" == "Catch2"
isEmpty(CATCH_INCLUDE_DIR): CATCH_INCLUDE_DIR=$$(CATCH_INCLUDE_DIR)
@if "%{CatchIncDir}" != ""
# set by Qt Creator wizard
@@ -119,6 +120,21 @@ isEmpty(CATCH_INCLUDE_DIR): {
}
SOURCES += \\
main.cpp \\
%{MainCppName} \\
%{TestCaseFileWithCppSuffix}
@endif
@if "%{TestFrameWork}" == "Catch2_dyn"
@if "%{Catch2Main}" == "true"
SOURCES = %{TestCaseFileWithCppSuffix} \\
%{MainCppName}
CATCH2_MAIN=0
@else
SOURCES = %{TestCaseFileWithCppSuffix}
CATCH2_MAIN=1
@endif
include(catch-common.pri)
@endif

View File

@@ -16,6 +16,12 @@ import qbs.FileInfo
import qbs.Environment
import qbs.File
@endif
@if "%{TestFrameWork}" == "Catch2_dyn"
import qbs.Environment
import qbs.File
import "catchCommon.js" as catchCommon
@endif
CppApplication {
@if "%{TestFrameWork}" == "QtTest"
@@ -197,5 +203,40 @@ CppApplication {
"%{TestCaseFileWithCppSuffix}",
]
@endif
@if "%{TestFrameWork}" == "Catch2_dyn"
property string catch2Dir: {
if (typeof Environment.getEnv("CATCH_INSTALL_DIR") === 'undefined') {
if ("%{CatchInstallDir}" === "") {
console.warn("Using Catch2 from system")
} else {
console.warn("Using Catch2 install dir specified at Qt Creator wizard")
console.log("set CATCH_INSTALL_DIR as environment variable or Qbs property to get rid of this message")
return "%{CatchInstallDir}";
}
return "";
} else {
return Environment.getEnv("CATCH_INSTALL_DIR");
}
}
Properties {
condition: catch2Dir !== "" && File.exists(catch2Dir)
cpp.includePaths: [].concat(catchCommon.getChildPath(qbs, catch2Dir, "include"));
cpp.libraryPaths: catchCommon.getChildPath(qbs, catch2Dir, "lib")
}
@if "%{Catch2Main}" == "false"
cpp.dynamicLibraries: base.concat(["Catch2Main", "Catch2"])
@else
cpp.dynamicLibraries: base.concat(["Catch2"])
@endif
files: [
@if "%{Catch2Main}" == "true"
"%{MainCppName}",
@endif
"%{TestCaseFileWithCppSuffix}",
]
@endif
}

View File

@@ -185,7 +185,7 @@ find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui)
@endif
add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix} main.cpp)
add_executable(%{TestCaseName} %{TestCaseFileWithCppSuffix} %{MainCppName})
add_test(NAME %{TestCaseName} COMMAND %{TestCaseName})
@if "%{Catch2NeedsQt}" == "true"
@@ -203,3 +203,43 @@ 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

View File

@@ -55,3 +55,22 @@ int main(int argc, char** argv)
}
@endif
@endif
@if "%{TestFrameWork}" == "Catch2_dyn" && "%{Catch2Main}" == "true"
#include <catch2/catch_session.hpp>
@if "%{Catch2NeedsQt}" == "true"
#include <QtGui/QGuiApplication>
@endif
int main( int argc, char* argv[] ) {
// your setup ...
@if "%{Catch2NeedsQt}" == "true"
QGuiApplication app(argc, argv);
@endif
int result = Catch::Session().run( argc, argv );
// your clean-up...
return result;
}
@endif