From 70ef2f7f12c2c62714a2e926679172142ea150ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 8 Dec 2019 15:55:04 +0100 Subject: [PATCH] Update building of examples for static lib --- CMakeLists.txt | 27 ++-- docs/list-of-examples.md | 2 - examples/000-CatchMain.cpp | 8 +- examples/010-TestCase.cpp | 3 +- examples/020-TestCase-1.cpp | 2 +- examples/200-Rpt-CatchMain.cpp | 27 ---- examples/207-Rpt-TeamCityReporter.cpp | 171 -------------------------- examples/CMakeLists.txt | 140 ++++----------------- 8 files changed, 51 insertions(+), 329 deletions(-) delete mode 100644 examples/200-Rpt-CatchMain.cpp delete mode 100644 examples/207-Rpt-TeamCityReporter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ee4c768..c5d86c7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,10 @@ if(NOT DEFINED PROJECT_NAME) set(NOT_SUBPROJECT ON) endif() +option(CATCH_BUILD_TESTING "Build SelfTest project" ON) +option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF) + + # Catch2's build breaks if done in-tree. You probably should not build # things in tree anyway, but we can allow projects that include Catch2 # as a subproject to build in-tree as long as it is not in our tree. @@ -28,20 +32,31 @@ set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SOURCES_DIR ${CATCH_DIR}/src/catch2) set(SELF_TEST_DIR ${CATCH_DIR}/tests/SelfTest) set(BENCHMARK_DIR ${CATCH_DIR}/tests/Benchmark) +set(EXAMPLES_DIR ${CATCH_DIR}/examples) add_subdirectory(src) -add_subdirectory(tests) + +# Build tests only if requested +if (BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT) + find_package(PythonInterp) + if (NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR "Python not found, but required for tests") + endif() + add_subdirectory(tests) +endif() + +if(CATCH_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + #option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF) -#option(CATCH_BUILD_TESTING "Build SelfTest project" ON) -#option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF) #option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF) #option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF) #option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON) #option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON) #option(CATCH_INSTALL_EXTRAS "Install extras alongside library" ON) # -# #set_property(GLOBAL PROPERTY USE_FOLDERS ON) # #if(USE_WMAIN) @@ -56,10 +71,6 @@ add_subdirectory(tests) # add_subdirectory(projects) #endif() # -#if(CATCH_BUILD_EXAMPLES) -# add_subdirectory(examples) -#endif() -# #if(CATCH_BUILD_EXTRA_TESTS) # add_subdirectory(projects/ExtraTests) #endif() diff --git a/docs/list-of-examples.md b/docs/list-of-examples.md index 95e7bda0..fd69cc84 100644 --- a/docs/list-of-examples.md +++ b/docs/list-of-examples.md @@ -10,8 +10,6 @@ - Fixture: [Sections](../examples/100-Fix-Section.cpp) - Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp) - BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp) -- Report: [Catch-provided main](../examples/200-Rpt-CatchMain.cpp) -- Report: [TeamCity reporter](../examples/207-Rpt-TeamCityReporter.cpp) - Listener: [Listeners](../examples/210-Evt-EventListeners.cpp) - Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp) - Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp) diff --git a/examples/000-CatchMain.cpp b/examples/000-CatchMain.cpp index 2894d425..0580b932 100644 --- a/examples/000-CatchMain.cpp +++ b/examples/000-CatchMain.cpp @@ -1,12 +1,10 @@ // 000-CatchMain.cpp -// In a Catch project with multiple files, dedicate one file to compile the -// source code of Catch itself and reuse the resulting object file for linking. +// It is generally recommended to have a single file provide the main +// of a testing binary, and other test files to link against it. // Let Catch provide main(): -#define CATCH_CONFIG_MAIN - -#include +#include // That's it diff --git a/examples/010-TestCase.cpp b/examples/010-TestCase.cpp index c00b8a8f..f8af548a 100644 --- a/examples/010-TestCase.cpp +++ b/examples/010-TestCase.cpp @@ -1,8 +1,9 @@ // 010-TestCase.cpp // Let Catch provide main(): -#define CATCH_CONFIG_MAIN +#include +// And write tests in the same file: #include int Factorial( int number ) { diff --git a/examples/020-TestCase-1.cpp b/examples/020-TestCase-1.cpp index ab0249e4..76e25dad 100644 --- a/examples/020-TestCase-1.cpp +++ b/examples/020-TestCase-1.cpp @@ -4,7 +4,7 @@ // source code of Catch itself and reuse the resulting object file for linking. // Let Catch provide main(): -#define CATCH_CONFIG_MAIN +#include #include diff --git a/examples/200-Rpt-CatchMain.cpp b/examples/200-Rpt-CatchMain.cpp deleted file mode 100644 index b84c804d..00000000 --- a/examples/200-Rpt-CatchMain.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// 200-Rpt-CatchMain.cpp - -// In a Catch project with multiple files, dedicate one file to compile the -// source code of Catch itself and reuse the resulting object file for linking. - -// Let Catch provide main(): -#define CATCH_CONFIG_MAIN - -#include - -#ifdef CATCH_EXAMPLE_RPT_1 -#include CATCH_EXAMPLE_RPT_1 -#endif - -#ifdef CATCH_EXAMPLE_RPT_2 -#include CATCH_EXAMPLE_RPT_2 -#endif - -#ifdef CATCH_EXAMPLE_RPT_3 -#include CATCH_EXAMPLE_RPT_3 -#endif - -// That's it - -// Compile implementation of Catch for use with files that do contain tests: -// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp -// cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp diff --git a/examples/207-Rpt-TeamCityReporter.cpp b/examples/207-Rpt-TeamCityReporter.cpp deleted file mode 100644 index d28460f4..00000000 --- a/examples/207-Rpt-TeamCityReporter.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// 207-Rpt-TeamCityReporter.cpp - -// Catch has built-in and external reporters: -// Built-in: -// - compact -// - console -// - junit -// - xml -// External: -// - automake -// - tap -// - teamcity (this example) - -// main() and reporter code provided in 200-Rpt-CatchMain.cpp - -#include - -#ifdef _MSC_VER -# pragma warning (disable : 4702) // Disable warning: unreachable code -#endif - -TEST_CASE( "TeamCity passes unconditionally succeeding assertion", "[teamcity]" ) { - - SUCCEED(); -} - -TEST_CASE( "TeamCity reports unconditionally failing assertion", "[teamcity]" ) { - - FAIL(); -} - -TEST_CASE( "TeamCity reports failing check", "[teamcity]" ) { - - REQUIRE( 3 == 7 ); -} - -TEST_CASE( "TeamCity reports failing check-false", "[teamcity]" ) { - - REQUIRE_FALSE( 3 == 3 ); -} - -TEST_CASE( "TeamCity reports failing check-that", "[teamcity]" ) { - - using namespace Catch; - - REQUIRE_THAT( "hello", Contains( "world" ) ); -} - -TEST_CASE( "TeamCity reports unexpected exception", "[teamcity]" ) { - - REQUIRE( (throw std::runtime_error("surprise!"), true) ); -} - -TEST_CASE( "TeamCity reports undesired exception", "[teamcity]" ) { - - REQUIRE_NOTHROW( (throw std::runtime_error("surprise!"), true) ); -} - -TEST_CASE( "TeamCity reports missing expected exception", "[teamcity]" ) { - - REQUIRE_THROWS( true ); -} - -TEST_CASE( "TeamCity reports missing specific expected exception", "[teamcity]" ) { - - REQUIRE_THROWS_AS( throw std::bad_alloc(), std::runtime_error ); -} - -TEST_CASE( "TeamCity reports unexpected message in expected exception", "[teamcity]" ) { - - using namespace Catch; - - CHECK_THROWS_WITH( throw std::runtime_error("hello"), "world" ); - CHECK_THROWS_WITH( throw std::runtime_error("hello"), Contains("world") ); -} - -struct MyException: public std::runtime_error -{ - MyException( char const * text ) - : std::runtime_error( text ) {} - - ~MyException() override; -}; - -// prevent -Wweak-vtables: -MyException::~MyException() = default; - -struct MyExceptionMatcher : Catch::MatcherBase< std::runtime_error > -{ - std::string m_text; - - MyExceptionMatcher( char const * text ) - : m_text( text ) - {} - - ~MyExceptionMatcher() override; - - bool match( std::runtime_error const & arg ) const override - { - return m_text == arg.what() ; - } - - std::string describe() const override - { - return "it's me"; - } -}; - -// prevent -Wweak-vtables: -MyExceptionMatcher::~MyExceptionMatcher() = default; - -TEST_CASE( "TeamCity failing check-throws-matches", "[teamcity]" ) { - - CHECK_THROWS_MATCHES( throw MyException("hello"), MyException, MyExceptionMatcher("world") ); -} - -// [!throws] - lets Catch know that this test is likely to throw an exception even if successful. -// This causes the test to be excluded when running with -e or --nothrow. - -// No special effects for the reporter. - -TEST_CASE( "TeamCity throwing exception with tag [!throws]", "[teamcity][!throws]" ) { - - REQUIRE_THROWS( throw std::runtime_error("unsurprisingly") ); -} - -// [!mayfail] - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests. - -TEST_CASE( "TeamCity failing assertion with tag [!mayfail]", "[teamcity][!mayfail] " ) { - - REQUIRE( 3 == 7 ); // doesn't fail test case this time, reports: testIgnored - REQUIRE( 3 == 3 ); -} - -// [!shouldfail] - like [!mayfail] but fails the test if it passes. -// This can be useful if you want to be notified of accidental, or third-party, fixes. - -TEST_CASE( "TeamCity succeeding assertion with tag [!shouldfail]", "[teamcity][!shouldfail]" ) { - - SUCCEED( "Marked [!shouldfail]" ); -} - -// Compile & run: -// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp -// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -o 207-Rpt-TeamCityReporter 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters -// -// - cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp -// - cl -EHsc -I%CATCH_ROOT% 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters - -// Compilation output (--list-reporters): -// Available reporters: -// compact: Reports test results on a single line, suitable for IDEs -// console: Reports test results as plain lines of text -// junit: Reports test results in an XML format that looks like Ant's -// junitreport target -// teamcity: Reports test results as TeamCity service messages -// xml: Reports test results as an XML document - -// Expected output (abbreviated and broken into shorter lines): -// -// prompt> 207-Rpt-TeamCityReporter.exe --reporter teamcity -// ##teamcity[testSuiteStarted name='207-Rpt-TeamCityReporter.exe'] -// ##teamcity[testStarted name='TeamCity passes unconditionally succeeding assertion'] -// ##teamcity[testFinished name='TeamCity passes unconditionally succeeding assertion' duration='1'] -// ##teamcity[testStarted name='TeamCity reports unconditionally failing assertion'] -// ##teamcity[testFailed name='TeamCity reports unconditionally failing assertion' / -// message='.../examples/207-Rpt-TeamCityReporter.cpp:23|n/ -// ...............................................................................|n|n/ -// .../examples/207-Rpt-TeamCityReporter.cpp:25|nexplicit failure'] -// ##teamcity[testFinished name='TeamCity reports unconditionally failing assertion' duration='3'] -// ... diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7526e47f..2fe5e688 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,44 +1,27 @@ -# -# Build examples. -# -# Requires CATCH_BUILD_EXAMPLES to be defined 'true', see ../CMakeLists.txt. -# +cmake_minimum_required( VERSION 3.5 ) -cmake_minimum_required( VERSION 3.0 ) - -project( CatchExamples CXX ) +project( Catch2Examples LANGUAGES CXX ) message( STATUS "Examples included" ) -# define folders used: -set( EXAMPLES_DIR ${CATCH_DIR}/examples ) -set( HEADER_DIR ${CATCH_DIR}/single_include ) -set( REPORTER_HEADER_DIR ${CATCH_DIR}/include/reporters ) - -# single-file sources: - -set( SOURCES_SINGLE_FILE - 010-TestCase.cpp - 231-Cfg-OutputStreams.cpp +# Some one-offs first: +# 1) Tests and main in one file +add_executable( 010-TestCase + 010-TestCase.cpp ) -# multiple-file modules: - -set( SOURCES_020 - 020-TestCase-1.cpp - 020-TestCase-2.cpp +# 2) Tests and main across two files +add_executable( 020-MultiFile + 020-TestCase-1.cpp + 020-TestCase-2.cpp ) -# main for idiomatic test sources: +# TODO: How to handle differently configured libraries? +# Needed in 231-Cfg-OutputStreams -set( SOURCES_IDIOMATIC_MAIN - 000-CatchMain.cpp -) - -# sources to combine with 000-CatchMain.cpp: - -set( SOURCES_IDIOMATIC_TESTS +# These examples use the standard separate compilation +set( SOURCES_IDIOMATIC_EXAMPLES 030-Asn-Require-Check.cpp 100-Fix-Section.cpp 110-Fix-ClassFixture.cpp @@ -50,94 +33,24 @@ set( SOURCES_IDIOMATIC_TESTS 311-Gen-CustomCapture.cpp ) -# main-s for reporter-specific test sources: +string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_EXAMPLES "${SOURCES_IDIOMATIC_EXAMPLES}" ) +set( TARGETS_IDIOMATIC_EXAMPLES ${BASENAMES_IDIOMATIC_EXAMPLES} ) -set( SOURCES_REPORTERS_MAIN - 200-Rpt-CatchMain.cpp -) -string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN 200-Rpt-CatchMain.cpp ) - -set( NAMES_REPORTERS TeamCity ) - -foreach( reporter ${NAMES_REPORTERS} ) - list( APPEND SOURCES_SPECIFIC_REPORTERS_MAIN ${BASENAMES_REPORTERS_MAIN}${reporter}.cpp ) +foreach( name ${TARGETS_IDIOMATIC_EXAMPLES} ) + add_executable( ${name} + 000-CatchMain.cpp + ${EXAMPLES_DIR}/${name}.cpp ) endforeach() -# sources to combine with 200-Rpt-CatchMain{Reporter}.cpp: - -set( SOURCES_REPORTERS_TESTS - 207-Rpt-TeamCityReporter.cpp +set(ALL_EXAMPLE_TARGETS + ${TARGETS_IDIOMATIC_EXAMPLES} + 010-TestCase + 020-MultiFile ) -# check if all sources are listed, warn if not: - -set( SOURCES_ALL - ${SOURCES_020} - ${SOURCES_SINGLE_FILE} - ${SOURCES_IDIOMATIC_MAIN} - ${SOURCES_IDIOMATIC_TESTS} - ${SOURCES_REPORTERS_MAIN} - ${SOURCES_REPORTERS_TESTS} -) - -foreach( name ${SOURCES_ALL} ) - list( APPEND SOURCES_ALL_PATH ${EXAMPLES_DIR}/${name} ) -endforeach() - -CheckFileList( SOURCES_ALL_PATH ${EXAMPLES_DIR} ) - -# create target names: - -string( REPLACE ".cpp" "" BASENAMES_SINGLE_FILE "${SOURCES_SINGLE_FILE}" ) -string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_TESTS "${SOURCES_IDIOMATIC_TESTS}" ) -string( REPLACE ".cpp" "" BASENAMES_REPORTERS_TESTS "${SOURCES_REPORTERS_TESTS}" ) -string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN "${SOURCES_REPORTERS_MAIN}" ) - -set( TARGETS_SINGLE_FILE ${BASENAMES_SINGLE_FILE} ) -set( TARGETS_IDIOMATIC_TESTS ${BASENAMES_IDIOMATIC_TESTS} ) -set( TARGETS_REPORTERS_TESTS ${BASENAMES_REPORTERS_TESTS} ) -set( TARGETS_REPORTERS_MAIN ${BASENAMES_REPORTERS_MAIN} ) - -set( TARGETS_ALL - ${TARGETS_SINGLE_FILE} - 020-TestCase - ${TARGETS_IDIOMATIC_TESTS} CatchMain - ${TARGETS_REPORTERS_TESTS} CatchMainTeamCity -) - -# define program targets: - -add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch2/catch.hpp ) -#add_library( CatchMainAutomake OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp ) -#add_library( CatchMainTap OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp ) -add_library( CatchMainTeamCity OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp ) - -#target_compile_definitions( CatchMainAutomake PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_automake.hpp\" ) -#target_compile_definitions( CatchMainTap PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_tap.hpp\" ) -target_compile_definitions( CatchMainTeamCity PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" ) - -foreach( name ${TARGETS_SINGLE_FILE} ) - add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch2/catch.hpp ) -endforeach() - -foreach( name ${TARGETS_IDIOMATIC_TESTS} ) - add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $ ${HEADER_DIR}/catch2/catch.hpp ) -endforeach() - -add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch2/catch.hpp ) - -#add_executable( 207-Rpt-AutomakeReporter ${EXAMPLES_DIR}/207-Rpt-AutomakeReporter.cpp $ ${HEADER_DIR}/catch2/catch.hpp ) -#add_executable( 207-Rpt-TapReporter ${EXAMPLES_DIR}/207-Rpt-TapReporter.cpp $ ${HEADER_DIR}/catch2/catch.hpp ) -add_executable( 207-Rpt-TeamCityReporter ${EXAMPLES_DIR}/207-Rpt-TeamCityReporter.cpp $ ${HEADER_DIR}/catch2/catch.hpp ) - -#foreach( name ${TARGETS_REPORTERS_TESTS} ) -# add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $ ${HEADER_DIR}/catch2/catch.hpp ) -#endforeach() - -foreach( name ${TARGETS_ALL} ) - target_include_directories( ${name} PRIVATE ${HEADER_DIR} ${CATCH_DIR} ) - +foreach( name ${ALL_EXAMPLE_TARGETS} ) + target_link_libraries( ${name} Catch2 ) set_property(TARGET ${name} PROPERTY CXX_STANDARD 14) set_property(TARGET ${name} PROPERTY CXX_EXTENSIONS OFF) @@ -154,4 +67,3 @@ foreach( name ${TARGETS_ALL} ) target_compile_options( ${name} PRIVATE /W4 /w44265 /WX ) endif() endforeach() -