ADD: added Catch2 test; added TrackClass
This commit is contained in:
15
libs/Catch2/examples/000-CatchMain.cpp
Normal file
15
libs/Catch2/examples/000-CatchMain.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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.
|
||||
|
||||
// Let Catch provide main():
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
// That's it
|
||||
|
||||
// Compile implementation of Catch for use with files that do contain tests:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 000-CatchMain.cpp
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 000-CatchMain.cpp
|
||||
36
libs/Catch2/examples/010-TestCase.cpp
Normal file
36
libs/Catch2/examples/010-TestCase.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// 010-TestCase.cpp
|
||||
|
||||
// Let Catch provide main():
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
int Factorial( int number ) {
|
||||
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
||||
// return number <= 1 ? 1 : Factorial( number - 1 ) * number; // pass
|
||||
}
|
||||
|
||||
TEST_CASE( "Factorial of 0 is 1 (fail)", "[single-file]" ) {
|
||||
REQUIRE( Factorial(0) == 1 );
|
||||
}
|
||||
|
||||
TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) {
|
||||
REQUIRE( Factorial(1) == 1 );
|
||||
REQUIRE( Factorial(2) == 2 );
|
||||
REQUIRE( Factorial(3) == 6 );
|
||||
REQUIRE( Factorial(10) == 3628800 );
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 010-TestCase.cpp && 010-TestCase --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 010-TestCase --reporter compact --success
|
||||
// 010-TestCase.cpp:14: failed: Factorial(0) == 1 for: 0 == 1
|
||||
// 010-TestCase.cpp:18: passed: Factorial(1) == 1 for: 1 == 1
|
||||
// 010-TestCase.cpp:19: passed: Factorial(2) == 2 for: 2 == 2
|
||||
// 010-TestCase.cpp:20: passed: Factorial(3) == 6 for: 6 == 6
|
||||
// 010-TestCase.cpp:21: passed: Factorial(10) == 3628800 for: 3628800 (0x375f00) == 3628800 (0x375f00)
|
||||
// Failed 1 test case, failed 1 assertion.
|
||||
35
libs/Catch2/examples/020-TestCase-1.cpp
Normal file
35
libs/Catch2/examples/020-TestCase-1.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// 020-TestCase-1.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 <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
|
||||
}
|
||||
|
||||
// ^^^
|
||||
// Normally no TEST_CASEs in this file.
|
||||
// Here just to show there are two source files via option --list-tests.
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success
|
||||
//
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 020-TestCase-1.cpp
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -Fe020-TestCase.exe 020-TestCase-1.obj 020-TestCase-2.cpp && 020-TestCase --success
|
||||
|
||||
// Expected test case listing:
|
||||
//
|
||||
// prompt> 020-TestCase --list-tests *
|
||||
// Matching test cases:
|
||||
// 1: All test cases reside in other .cpp files (empty)
|
||||
// [multi-file:1]
|
||||
// 2: Factorial of 0 is computed (fail)
|
||||
// [multi-file:2]
|
||||
// 2: Factorials of 1 and higher are computed (pass)
|
||||
// [multi-file:2]
|
||||
// 3 matching test cases
|
||||
33
libs/Catch2/examples/020-TestCase-2.cpp
Normal file
33
libs/Catch2/examples/020-TestCase-2.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// 020-TestCase-2.cpp
|
||||
|
||||
// main() provided by Catch in file 020-TestCase-1.cpp.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
int Factorial( int number ) {
|
||||
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
||||
// return number <= 1 ? 1 : Factorial( number - 1 ) * number; // pass
|
||||
}
|
||||
|
||||
TEST_CASE( "2: Factorial of 0 is 1 (fail)", "[multi-file:2]" ) {
|
||||
REQUIRE( Factorial(0) == 1 );
|
||||
}
|
||||
|
||||
TEST_CASE( "2: Factorials of 1 and higher are computed (pass)", "[multi-file:2]" ) {
|
||||
REQUIRE( Factorial(1) == 1 );
|
||||
REQUIRE( Factorial(2) == 2 );
|
||||
REQUIRE( Factorial(3) == 6 );
|
||||
REQUIRE( Factorial(10) == 3628800 );
|
||||
}
|
||||
|
||||
// Compile: see 020-TestCase-1.cpp
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 020-TestCase --reporter compact --success
|
||||
// 020-TestCase-2.cpp:13: failed: Factorial(0) == 1 for: 0 == 1
|
||||
// 020-TestCase-2.cpp:17: passed: Factorial(1) == 1 for: 1 == 1
|
||||
// 020-TestCase-2.cpp:18: passed: Factorial(2) == 2 for: 2 == 2
|
||||
// 020-TestCase-2.cpp:19: passed: Factorial(3) == 6 for: 6 == 6
|
||||
// 020-TestCase-2.cpp:20: passed: Factorial(10) == 3628800 for: 3628800 (0x375f00) == 3628800 (0x375f00)
|
||||
// Failed 1 test case, failed 1 assertion.
|
||||
74
libs/Catch2/examples/030-Asn-Require-Check.cpp
Normal file
74
libs/Catch2/examples/030-Asn-Require-Check.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// 030-Asn-Require-Check.cpp
|
||||
|
||||
// Catch has two natural expression assertion macro's:
|
||||
// - REQUIRE() stops at first failure.
|
||||
// - CHECK() continues after failure.
|
||||
|
||||
// There are two variants to support decomposing negated expressions:
|
||||
// - REQUIRE_FALSE() stops at first failure.
|
||||
// - CHECK_FALSE() continues after failure.
|
||||
|
||||
// main() provided in 000-CatchMain.cpp
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
std::string one() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is true (pass)", "[require]" ) {
|
||||
REQUIRE( one() == "1" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is true (fail)", "[require]" ) {
|
||||
REQUIRE( one() == "x" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is true (stop at first failure)", "[require]" ) {
|
||||
WARN( "REQUIRE stops at first failure:" );
|
||||
|
||||
REQUIRE( one() == "x" );
|
||||
REQUIRE( one() == "1" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is true (continue after failure)", "[check]" ) {
|
||||
WARN( "CHECK continues after failure:" );
|
||||
|
||||
CHECK( one() == "x" );
|
||||
REQUIRE( one() == "1" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is false (stops at first failure)", "[require-false]" ) {
|
||||
WARN( "REQUIRE_FALSE stops at first failure:" );
|
||||
|
||||
REQUIRE_FALSE( one() == "1" );
|
||||
REQUIRE_FALSE( one() != "1" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assert that something is false (continue after failure)", "[check-false]" ) {
|
||||
WARN( "CHECK_FALSE continues after failure:" );
|
||||
|
||||
CHECK_FALSE( one() == "1" );
|
||||
REQUIRE_FALSE( one() != "1" );
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp 000-CatchMain.o && 030-Asn-Require-Check --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 030-Asn-Require-Check.cpp 000-CatchMain.obj && 030-Asn-Require-Check --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 030-Asn-Require-Check.exe --reporter compact --success
|
||||
// 030-Asn-Require-Check.cpp:20: passed: one() == "1" for: "1" == "1"
|
||||
// 030-Asn-Require-Check.cpp:24: failed: one() == "x" for: "1" == "x"
|
||||
// 030-Asn-Require-Check.cpp:28: warning: 'REQUIRE stops at first failure:'
|
||||
// 030-Asn-Require-Check.cpp:30: failed: one() == "x" for: "1" == "x"
|
||||
// 030-Asn-Require-Check.cpp:35: warning: 'CHECK continues after failure:'
|
||||
// 030-Asn-Require-Check.cpp:37: failed: one() == "x" for: "1" == "x"
|
||||
// 030-Asn-Require-Check.cpp:38: passed: one() == "1" for: "1" == "1"
|
||||
// 030-Asn-Require-Check.cpp:42: warning: 'REQUIRE_FALSE stops at first failure:'
|
||||
// 030-Asn-Require-Check.cpp:44: failed: !(one() == "1") for: !("1" == "1")
|
||||
// 030-Asn-Require-Check.cpp:49: warning: 'CHECK_FALSE continues after failure:'
|
||||
// 030-Asn-Require-Check.cpp:51: failed: !(one() == "1") for: !("1" == "1")
|
||||
// 030-Asn-Require-Check.cpp:52: passed: !(one() != "1") for: !("1" != "1")
|
||||
// Failed 5 test cases, failed 5 assertions.
|
||||
69
libs/Catch2/examples/100-Fix-Section.cpp
Normal file
69
libs/Catch2/examples/100-Fix-Section.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// 100-Fix-Section.cpp
|
||||
|
||||
// Catch has two ways to express fixtures:
|
||||
// - Sections (this file)
|
||||
// - Traditional class-based fixtures
|
||||
|
||||
// main() provided in 000-CatchMain.cpp
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
|
||||
|
||||
// For each section, vector v is anew:
|
||||
|
||||
std::vector<int> v( 5 );
|
||||
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
|
||||
SECTION( "resizing bigger changes size and capacity" ) {
|
||||
v.resize( 10 );
|
||||
|
||||
REQUIRE( v.size() == 10 );
|
||||
REQUIRE( v.capacity() >= 10 );
|
||||
}
|
||||
SECTION( "resizing smaller changes size but not capacity" ) {
|
||||
v.resize( 0 );
|
||||
|
||||
REQUIRE( v.size() == 0 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
}
|
||||
SECTION( "reserving bigger changes capacity but not size" ) {
|
||||
v.reserve( 10 );
|
||||
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 10 );
|
||||
}
|
||||
SECTION( "reserving smaller does not change size or capacity" ) {
|
||||
v.reserve( 0 );
|
||||
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
}
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp 000-CatchMain.o && 100-Fix-Section --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 100-Fix-Section.cpp 000-CatchMain.obj && 100-Fix-Section --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 100-Fix-Section.exe --reporter compact --success
|
||||
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 100-Fix-Section.cpp:23: passed: v.size() == 10 for: 10 == 10
|
||||
// 100-Fix-Section.cpp:24: passed: v.capacity() >= 10 for: 10 >= 10
|
||||
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 100-Fix-Section.cpp:29: passed: v.size() == 0 for: 0 == 0
|
||||
// 100-Fix-Section.cpp:30: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 100-Fix-Section.cpp:35: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:36: passed: v.capacity() >= 10 for: 10 >= 10
|
||||
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 100-Fix-Section.cpp:41: passed: v.size() == 5 for: 5 == 5
|
||||
// 100-Fix-Section.cpp:42: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// Passed 1 test case with 16 assertions.
|
||||
63
libs/Catch2/examples/110-Fix-ClassFixture.cpp
Normal file
63
libs/Catch2/examples/110-Fix-ClassFixture.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// 110-Fix-ClassFixture.cpp
|
||||
|
||||
// Catch has two ways to express fixtures:
|
||||
// - Sections
|
||||
// - Traditional class-based fixtures (this file)
|
||||
|
||||
// main() provided in 000-CatchMain.cpp
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
class DBConnection
|
||||
{
|
||||
public:
|
||||
static DBConnection createConnection( std::string const & /*dbName*/ ) {
|
||||
return DBConnection();
|
||||
}
|
||||
|
||||
bool executeSQL( std::string const & /*query*/, int const /*id*/, std::string const & arg ) {
|
||||
if ( arg.length() == 0 ) {
|
||||
throw std::logic_error("empty SQL query argument");
|
||||
}
|
||||
return true; // ok
|
||||
}
|
||||
};
|
||||
|
||||
class UniqueTestsFixture
|
||||
{
|
||||
protected:
|
||||
UniqueTestsFixture()
|
||||
: conn( DBConnection::createConnection( "myDB" ) )
|
||||
{}
|
||||
|
||||
int getID() {
|
||||
return ++uniqueID;
|
||||
}
|
||||
|
||||
protected:
|
||||
DBConnection conn;
|
||||
|
||||
private:
|
||||
static int uniqueID;
|
||||
};
|
||||
|
||||
int UniqueTestsFixture::uniqueID = 0;
|
||||
|
||||
TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/No Name", "[create]" ) {
|
||||
REQUIRE_THROWS( conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "") );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/Normal", "[create]" ) {
|
||||
REQUIRE( conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs" ) );
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp 000-CatchMain.o && 110-Fix-ClassFixture --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 110-Fix-ClassFixture.cpp 000-CatchMain.obj && 110-Fix-ClassFixture --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 110-Fix-ClassFixture.exe --reporter compact --success
|
||||
// 110-Fix-ClassFixture.cpp:47: passed: conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "")
|
||||
// 110-Fix-ClassFixture.cpp:51: passed: conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs" ) for: true
|
||||
// Passed both 2 test cases with 2 assertions.
|
||||
73
libs/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
Normal file
73
libs/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp
|
||||
|
||||
// main() provided in 000-CatchMain.cpp
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
SCENARIO( "vectors can be sized and resized", "[vector]" ) {
|
||||
|
||||
GIVEN( "A vector with some items" ) {
|
||||
std::vector<int> v( 5 );
|
||||
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
|
||||
WHEN( "the size is increased" ) {
|
||||
v.resize( 10 );
|
||||
|
||||
THEN( "the size and capacity change" ) {
|
||||
REQUIRE( v.size() == 10 );
|
||||
REQUIRE( v.capacity() >= 10 );
|
||||
}
|
||||
}
|
||||
WHEN( "the size is reduced" ) {
|
||||
v.resize( 0 );
|
||||
|
||||
THEN( "the size changes but not capacity" ) {
|
||||
REQUIRE( v.size() == 0 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
}
|
||||
}
|
||||
WHEN( "more capacity is reserved" ) {
|
||||
v.reserve( 10 );
|
||||
|
||||
THEN( "the capacity changes but not the size" ) {
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 10 );
|
||||
}
|
||||
}
|
||||
WHEN( "less capacity is reserved" ) {
|
||||
v.reserve( 0 );
|
||||
|
||||
THEN( "neither size nor capacity are changed" ) {
|
||||
REQUIRE( v.size() == 5 );
|
||||
REQUIRE( v.capacity() >= 5 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp 000-CatchMain.o && 120-Bdd-ScenarioGivenWhenThen --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 120-Bdd-ScenarioGivenWhenThen.cpp 000-CatchMain.obj && 120-Bdd-ScenarioGivenWhenThen --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 120-Bdd-ScenarioGivenWhenThen.exe --reporter compact --success
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:19: passed: v.size() == 10 for: 10 == 10
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:20: passed: v.capacity() >= 10 for: 10 >= 10
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:27: passed: v.size() == 0 for: 0 == 0
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:28: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:35: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:36: passed: v.capacity() >= 10 for: 10 >= 10
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:43: passed: v.size() == 5 for: 5 == 5
|
||||
// 120-Bdd-ScenarioGivenWhenThen.cpp:44: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
// Passed 1 test case with 16 assertions.
|
||||
27
libs/Catch2/examples/200-Rpt-CatchMain.cpp
Normal file
27
libs/Catch2/examples/200-Rpt-CatchMain.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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 <catch2/catch.hpp>
|
||||
|
||||
#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
|
||||
171
libs/Catch2/examples/207-Rpt-TeamCityReporter.cpp
Normal file
171
libs/Catch2/examples/207-Rpt-TeamCityReporter.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
// 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 <catch2/catch.hpp>
|
||||
|
||||
#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']
|
||||
// ...
|
||||
422
libs/Catch2/examples/210-Evt-EventListeners.cpp
Normal file
422
libs/Catch2/examples/210-Evt-EventListeners.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
// 210-Evt-EventListeners.cpp
|
||||
|
||||
// Contents:
|
||||
// 1. Printing of listener data
|
||||
// 2. My listener and registration
|
||||
// 3. Test cases
|
||||
|
||||
// main() provided in 000-CatchMain.cpp
|
||||
|
||||
// Let Catch provide the required interfaces:
|
||||
#define CATCH_CONFIG_EXTERNAL_INTERFACES
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 1. Printing of listener data:
|
||||
//
|
||||
|
||||
std::string ws(int const level) {
|
||||
return std::string( 2 * level, ' ' );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
std::ostream& operator<<( std::ostream& os, std::vector<T> const& v ) {
|
||||
os << "{ ";
|
||||
for ( const auto& x : v )
|
||||
os << x << ", ";
|
||||
return os << "}";
|
||||
}
|
||||
|
||||
// struct SourceLineInfo {
|
||||
// char const* file;
|
||||
// std::size_t line;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::SourceLineInfo const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- file: " << info.file << "\n"
|
||||
<< ws(level+1) << "- line: " << info.line << "\n";
|
||||
}
|
||||
|
||||
//struct MessageInfo {
|
||||
// std::string macroName;
|
||||
// std::string message;
|
||||
// SourceLineInfo lineInfo;
|
||||
// ResultWas::OfType type;
|
||||
// unsigned int sequence;
|
||||
//};
|
||||
|
||||
void print( std::ostream& os, int const level, Catch::MessageInfo const& info ) {
|
||||
os << ws(level+1) << "- macroName: '" << info.macroName << "'\n"
|
||||
<< ws(level+1) << "- message '" << info.message << "'\n";
|
||||
print( os,level+1 , "- lineInfo", info.lineInfo );
|
||||
os << ws(level+1) << "- sequence " << info.sequence << "\n";
|
||||
}
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, std::vector<Catch::MessageInfo> const& v ) {
|
||||
os << ws(level ) << title << ":\n";
|
||||
for ( const auto& x : v )
|
||||
{
|
||||
os << ws(level+1) << "{\n";
|
||||
print( os, level+2, x );
|
||||
os << ws(level+1) << "}\n";
|
||||
}
|
||||
// os << ws(level+1) << "\n";
|
||||
}
|
||||
|
||||
// struct TestRunInfo {
|
||||
// std::string name;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunInfo const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- name: " << info.name << "\n";
|
||||
}
|
||||
|
||||
// struct Counts {
|
||||
// std::size_t total() const;
|
||||
// bool allPassed() const;
|
||||
// bool allOk() const;
|
||||
//
|
||||
// std::size_t passed = 0;
|
||||
// std::size_t failed = 0;
|
||||
// std::size_t failedButOk = 0;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::Counts const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- total(): " << info.total() << "\n"
|
||||
<< ws(level+1) << "- allPassed(): " << info.allPassed() << "\n"
|
||||
<< ws(level+1) << "- allOk(): " << info.allOk() << "\n"
|
||||
<< ws(level+1) << "- passed: " << info.passed << "\n"
|
||||
<< ws(level+1) << "- failed: " << info.failed << "\n"
|
||||
<< ws(level+1) << "- failedButOk: " << info.failedButOk << "\n";
|
||||
}
|
||||
|
||||
// struct Totals {
|
||||
// Counts assertions;
|
||||
// Counts testCases;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::Totals const& info ) {
|
||||
os << ws(level) << title << ":\n";
|
||||
print( os, level+1, "- assertions", info.assertions );
|
||||
print( os, level+1, "- testCases" , info.testCases );
|
||||
}
|
||||
|
||||
// struct TestRunStats {
|
||||
// TestRunInfo runInfo;
|
||||
// Totals totals;
|
||||
// bool aborting;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunStats const& info ) {
|
||||
os << ws(level) << title << ":\n";
|
||||
print( os, level+1 , "- runInfo", info.runInfo );
|
||||
print( os, level+1 , "- totals" , info.totals );
|
||||
os << ws(level+1) << "- aborting: " << info.aborting << "\n";
|
||||
}
|
||||
|
||||
// struct TestCaseInfo {
|
||||
// enum SpecialProperties{
|
||||
// None = 0,
|
||||
// IsHidden = 1 << 1,
|
||||
// ShouldFail = 1 << 2,
|
||||
// MayFail = 1 << 3,
|
||||
// Throws = 1 << 4,
|
||||
// NonPortable = 1 << 5,
|
||||
// Benchmark = 1 << 6
|
||||
// };
|
||||
//
|
||||
// bool isHidden() const;
|
||||
// bool throws() const;
|
||||
// bool okToFail() const;
|
||||
// bool expectedToFail() const;
|
||||
//
|
||||
// std::string tagsAsString() const;
|
||||
//
|
||||
// std::string name;
|
||||
// std::string className;
|
||||
// std::string description;
|
||||
// std::vector<std::string> tags;
|
||||
// std::vector<std::string> lcaseTags;
|
||||
// SourceLineInfo lineInfo;
|
||||
// SpecialProperties properties;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseInfo const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- isHidden(): " << info.isHidden() << "\n"
|
||||
<< ws(level+1) << "- throws(): " << info.throws() << "\n"
|
||||
<< ws(level+1) << "- okToFail(): " << info.okToFail() << "\n"
|
||||
<< ws(level+1) << "- expectedToFail(): " << info.expectedToFail() << "\n"
|
||||
<< ws(level+1) << "- tagsAsString(): '" << info.tagsAsString() << "'\n"
|
||||
<< ws(level+1) << "- name: '" << info.name << "'\n"
|
||||
<< ws(level+1) << "- className: '" << info.className << "'\n"
|
||||
<< ws(level+1) << "- description: '" << info.description << "'\n"
|
||||
<< ws(level+1) << "- tags: " << info.tags << "\n"
|
||||
<< ws(level+1) << "- lcaseTags: " << info.lcaseTags << "\n";
|
||||
print( os, level+1 , "- lineInfo", info.lineInfo );
|
||||
os << ws(level+1) << "- properties (flags): 0x" << std::hex << info.properties << std::dec << "\n";
|
||||
}
|
||||
|
||||
// struct TestCaseStats {
|
||||
// TestCaseInfo testInfo;
|
||||
// Totals totals;
|
||||
// std::string stdOut;
|
||||
// std::string stdErr;
|
||||
// bool aborting;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseStats const& info ) {
|
||||
os << ws(level ) << title << ":\n";
|
||||
print( os, level+1 , "- testInfo", info.testInfo );
|
||||
print( os, level+1 , "- totals" , info.totals );
|
||||
os << ws(level+1) << "- stdOut: " << info.stdOut << "\n"
|
||||
<< ws(level+1) << "- stdErr: " << info.stdErr << "\n"
|
||||
<< ws(level+1) << "- aborting: " << info.aborting << "\n";
|
||||
}
|
||||
|
||||
// struct SectionInfo {
|
||||
// std::string name;
|
||||
// std::string description;
|
||||
// SourceLineInfo lineInfo;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- name: " << info.name << "\n";
|
||||
print( os, level+1 , "- lineInfo", info.lineInfo );
|
||||
}
|
||||
|
||||
// struct SectionStats {
|
||||
// SectionInfo sectionInfo;
|
||||
// Counts assertions;
|
||||
// double durationInSeconds;
|
||||
// bool missingAssertions;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionStats const& info ) {
|
||||
os << ws(level ) << title << ":\n";
|
||||
print( os, level+1 , "- sectionInfo", info.sectionInfo );
|
||||
print( os, level+1 , "- assertions" , info.assertions );
|
||||
os << ws(level+1) << "- durationInSeconds: " << info.durationInSeconds << "\n"
|
||||
<< ws(level+1) << "- missingAssertions: " << info.missingAssertions << "\n";
|
||||
}
|
||||
|
||||
// struct AssertionInfo
|
||||
// {
|
||||
// StringRef macroName;
|
||||
// SourceLineInfo lineInfo;
|
||||
// StringRef capturedExpression;
|
||||
// ResultDisposition::Flags resultDisposition;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionInfo const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- macroName: '" << info.macroName << "'\n";
|
||||
print( os, level+1 , "- lineInfo" , info.lineInfo );
|
||||
os << ws(level+1) << "- capturedExpression: '" << info.capturedExpression << "'\n"
|
||||
<< ws(level+1) << "- resultDisposition (flags): 0x" << std::hex << info.resultDisposition << std::dec << "\n";
|
||||
}
|
||||
|
||||
//struct AssertionResultData
|
||||
//{
|
||||
// std::string reconstructExpression() const;
|
||||
//
|
||||
// std::string message;
|
||||
// mutable std::string reconstructedExpression;
|
||||
// LazyExpression lazyExpression;
|
||||
// ResultWas::OfType resultType;
|
||||
//};
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResultData const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- reconstructExpression(): '" << info.reconstructExpression() << "'\n"
|
||||
<< ws(level+1) << "- message: '" << info.message << "'\n"
|
||||
<< ws(level+1) << "- lazyExpression: '" << "(info.lazyExpression)" << "'\n"
|
||||
<< ws(level+1) << "- resultType: '" << info.resultType << "'\n";
|
||||
}
|
||||
|
||||
//class AssertionResult {
|
||||
// bool isOk() const;
|
||||
// bool succeeded() const;
|
||||
// ResultWas::OfType getResultType() const;
|
||||
// bool hasExpression() const;
|
||||
// bool hasMessage() const;
|
||||
// std::string getExpression() const;
|
||||
// std::string getExpressionInMacro() const;
|
||||
// bool hasExpandedExpression() const;
|
||||
// std::string getExpandedExpression() const;
|
||||
// std::string getMessage() const;
|
||||
// SourceLineInfo getSourceInfo() const;
|
||||
// std::string getTestMacroName() const;
|
||||
//
|
||||
// AssertionInfo m_info;
|
||||
// AssertionResultData m_resultData;
|
||||
//};
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResult const& info ) {
|
||||
os << ws(level ) << title << ":\n"
|
||||
<< ws(level+1) << "- isOk(): " << info.isOk() << "\n"
|
||||
<< ws(level+1) << "- succeeded(): " << info.succeeded() << "\n"
|
||||
<< ws(level+1) << "- getResultType(): " << info.getResultType() << "\n"
|
||||
<< ws(level+1) << "- hasExpression(): " << info.hasExpression() << "\n"
|
||||
<< ws(level+1) << "- hasMessage(): " << info.hasMessage() << "\n"
|
||||
<< ws(level+1) << "- getExpression(): '" << info.getExpression() << "'\n"
|
||||
<< ws(level+1) << "- getExpressionInMacro(): '" << info.getExpressionInMacro() << "'\n"
|
||||
<< ws(level+1) << "- hasExpandedExpression(): " << info.hasExpandedExpression() << "\n"
|
||||
<< ws(level+1) << "- getExpandedExpression(): " << info.getExpandedExpression() << "'\n"
|
||||
<< ws(level+1) << "- getMessage(): '" << info.getMessage() << "'\n";
|
||||
print( os, level+1 , "- getSourceInfo(): ", info.getSourceInfo() );
|
||||
os << ws(level+1) << "- getTestMacroName(): '" << info.getTestMacroName() << "'\n";
|
||||
|
||||
// print( os, level+1 , "- *** m_info (AssertionInfo)", info.m_info );
|
||||
// print( os, level+1 , "- *** m_resultData (AssertionResultData)", info.m_resultData );
|
||||
}
|
||||
|
||||
// struct AssertionStats {
|
||||
// AssertionResult assertionResult;
|
||||
// std::vector<MessageInfo> infoMessages;
|
||||
// Totals totals;
|
||||
// };
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionStats const& info ) {
|
||||
os << ws(level ) << title << ":\n";
|
||||
print( os, level+1 , "- assertionResult", info.assertionResult );
|
||||
print( os, level+1 , "- infoMessages", info.infoMessages );
|
||||
print( os, level+1 , "- totals", info.totals );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 2. My listener and registration:
|
||||
//
|
||||
|
||||
char const * dashed_line =
|
||||
"--------------------------------------------------------------------------";
|
||||
|
||||
struct MyListener : Catch::TestEventListenerBase {
|
||||
|
||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||
|
||||
// Get rid of Wweak-tables
|
||||
~MyListener();
|
||||
|
||||
// The whole test run starting
|
||||
void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
|
||||
std::cout
|
||||
<< std::boolalpha
|
||||
<< "\nEvent: testRunStarting:\n";
|
||||
print( std::cout, 1, "- testRunInfo", testRunInfo );
|
||||
}
|
||||
|
||||
// The whole test run ending
|
||||
void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: testRunEnded:\n";
|
||||
print( std::cout, 1, "- testRunStats", testRunStats );
|
||||
}
|
||||
|
||||
// A test is being skipped (because it is "hidden")
|
||||
void skipTest( Catch::TestCaseInfo const& testInfo ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: skipTest:\n";
|
||||
print( std::cout, 1, "- testInfo", testInfo );
|
||||
}
|
||||
|
||||
// Test cases starting
|
||||
void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: testCaseStarting:\n";
|
||||
print( std::cout, 1, "- testInfo", testInfo );
|
||||
}
|
||||
|
||||
// Test cases ending
|
||||
void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
std::cout << "\nEvent: testCaseEnded:\n";
|
||||
print( std::cout, 1, "testCaseStats", testCaseStats );
|
||||
}
|
||||
|
||||
// Sections starting
|
||||
void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
|
||||
std::cout << "\nEvent: sectionStarting:\n";
|
||||
print( std::cout, 1, "- sectionInfo", sectionInfo );
|
||||
}
|
||||
|
||||
// Sections ending
|
||||
void sectionEnded( Catch::SectionStats const& sectionStats ) override {
|
||||
std::cout << "\nEvent: sectionEnded:\n";
|
||||
print( std::cout, 1, "- sectionStats", sectionStats );
|
||||
}
|
||||
|
||||
// Assertions before/ after
|
||||
void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
|
||||
std::cout << "\nEvent: assertionStarting:\n";
|
||||
print( std::cout, 1, "- assertionInfo", assertionInfo );
|
||||
}
|
||||
|
||||
bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
|
||||
std::cout << "\nEvent: assertionEnded:\n";
|
||||
print( std::cout, 1, "- assertionStats", assertionStats );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CATCH_REGISTER_LISTENER( MyListener )
|
||||
|
||||
// Get rid of Wweak-tables
|
||||
MyListener::~MyListener() {}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 3. Test cases:
|
||||
//
|
||||
|
||||
TEST_CASE( "1: Hidden testcase", "[.hidden]" ) {
|
||||
}
|
||||
|
||||
TEST_CASE( "2: Testcase with sections", "[tag-A][tag-B]" ) {
|
||||
|
||||
int i = 42;
|
||||
|
||||
REQUIRE( i == 42 );
|
||||
|
||||
SECTION("Section 1") {
|
||||
INFO("Section 1");
|
||||
i = 7;
|
||||
SECTION("Section 1.1") {
|
||||
INFO("Section 1.1");
|
||||
REQUIRE( i == 42 );
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Section 2") {
|
||||
INFO("Section 2");
|
||||
REQUIRE( i == 42 );
|
||||
}
|
||||
WARN("At end of test case");
|
||||
}
|
||||
|
||||
struct Fixture {
|
||||
int fortytwo() const {
|
||||
return 42;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD( Fixture, "3: Testcase with class-based fixture", "[tag-C][tag-D]" ) {
|
||||
REQUIRE( fortytwo() == 42 );
|
||||
}
|
||||
|
||||
// Compile & run:
|
||||
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp 000-CatchMain.o && 210-Evt-EventListeners --success
|
||||
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 210-Evt-EventListeners.cpp 000-CatchMain.obj && 210-Evt-EventListeners --success
|
||||
|
||||
// Expected compact output (all assertions):
|
||||
//
|
||||
// prompt> 210-Evt-EventListeners --reporter compact --success
|
||||
// result omitted for brevity.
|
||||
56
libs/Catch2/examples/231-Cfg-OutputStreams.cpp
Normal file
56
libs/Catch2/examples/231-Cfg-OutputStreams.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// 231-Cfg-OutputStreams.cpp
|
||||
// Show how to replace the streams with a simple custom made streambuf.
|
||||
|
||||
// Note that this reimplementation _does not_ follow `std::cerr`
|
||||
// semantic, because it buffers the output. For most uses however,
|
||||
// there is no important difference between having `std::cerr` buffered
|
||||
// or unbuffered.
|
||||
|
||||
#define CATCH_CONFIG_NOSTDOUT
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
|
||||
class out_buff : public std::stringbuf {
|
||||
std::FILE* m_stream;
|
||||
public:
|
||||
out_buff(std::FILE* stream):m_stream(stream) {}
|
||||
~out_buff();
|
||||
int sync() override {
|
||||
int ret = 0;
|
||||
for (unsigned char c : str()) {
|
||||
if (putc(c, m_stream) == EOF) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Reset the buffer to avoid printing it multiple times
|
||||
str("");
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
out_buff::~out_buff() { pubsync(); }
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wexit-time-destructors" // static variables in cout/cerr/clog
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
std::ostream& cout() {
|
||||
static std::ostream ret(new out_buff(stdout));
|
||||
return ret;
|
||||
}
|
||||
std::ostream& clog() {
|
||||
static std::ostream ret(new out_buff(stderr));
|
||||
return ret;
|
||||
}
|
||||
std::ostream& cerr() {
|
||||
return clog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("This binary uses putc to write out output", "[compilation-only]") {
|
||||
SUCCEED("Nothing to test.");
|
||||
}
|
||||
59
libs/Catch2/examples/300-Gen-OwnGenerator.cpp
Normal file
59
libs/Catch2/examples/300-Gen-OwnGenerator.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// 300-Gen-OwnGenerator.cpp
|
||||
// Shows how to define a custom generator.
|
||||
|
||||
// Specifically we will implement a random number generator for integers
|
||||
// It will have infinite capacity and settable lower/upper bound
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
// This class shows how to implement a simple generator for Catch tests
|
||||
class RandomIntGenerator : public Catch::Generators::IGenerator<int> {
|
||||
std::minstd_rand m_rand;
|
||||
std::uniform_int_distribution<> m_dist;
|
||||
int current_number;
|
||||
public:
|
||||
|
||||
RandomIntGenerator(int low, int high):
|
||||
m_rand(std::random_device{}()),
|
||||
m_dist(low, high)
|
||||
{
|
||||
static_cast<void>(next());
|
||||
}
|
||||
|
||||
int const& get() const override;
|
||||
bool next() override {
|
||||
current_number = m_dist(m_rand);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Avoids -Wweak-vtables
|
||||
int const& RandomIntGenerator::get() const {
|
||||
return current_number;
|
||||
}
|
||||
|
||||
// This helper function provides a nicer UX when instantiating the generator
|
||||
// Notice that it returns an instance of GeneratorWrapper<int>, which
|
||||
// is a value-wrapper around std::unique_ptr<IGenerator<int>>.
|
||||
Catch::Generators::GeneratorWrapper<int> random(int low, int high) {
|
||||
return Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new RandomIntGenerator(low, high)));
|
||||
}
|
||||
|
||||
// The two sections in this test case are equivalent, but the first one
|
||||
// is much more readable/nicer to use
|
||||
TEST_CASE("Generating random ints", "[example][generator]") {
|
||||
SECTION("Nice UX") {
|
||||
auto i = GENERATE(take(100, random(-100, 100)));
|
||||
REQUIRE(i >= -100);
|
||||
REQUIRE(i <= 100);
|
||||
}
|
||||
SECTION("Creating the random generator directly") {
|
||||
auto i = GENERATE(take(100, GeneratorWrapper<int>(std::unique_ptr<IGenerator<int>>(new RandomIntGenerator(-100, 100)))));
|
||||
REQUIRE(i >= -100);
|
||||
REQUIRE(i <= 100);
|
||||
}
|
||||
}
|
||||
|
||||
// Compiling and running this file will result in 400 successful assertions
|
||||
58
libs/Catch2/examples/301-Gen-MapTypeConversion.cpp
Normal file
58
libs/Catch2/examples/301-Gen-MapTypeConversion.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// 301-Gen-MapTypeConversion.cpp
|
||||
// Shows how to use map to modify generator's return type.
|
||||
|
||||
// Specifically we wrap a std::string returning generator with a generator
|
||||
// that converts the strings using stoi, so the returned type is actually
|
||||
// an int.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
// Returns a line from a stream. You could have it e.g. read lines from
|
||||
// a file, but to avoid problems with paths in examples, we will use
|
||||
// a fixed stringstream.
|
||||
class LineGenerator : public Catch::Generators::IGenerator<std::string> {
|
||||
std::string m_line;
|
||||
std::stringstream m_stream;
|
||||
public:
|
||||
LineGenerator() {
|
||||
m_stream.str("1\n2\n3\n4\n");
|
||||
if (!next()) {
|
||||
throw Catch::GeneratorException("Couldn't read a single line");
|
||||
}
|
||||
}
|
||||
|
||||
std::string const& get() const override;
|
||||
|
||||
bool next() override {
|
||||
return !!std::getline(m_stream, m_line);
|
||||
}
|
||||
};
|
||||
|
||||
std::string const& LineGenerator::get() const {
|
||||
return m_line;
|
||||
}
|
||||
|
||||
// This helper function provides a nicer UX when instantiating the generator
|
||||
// Notice that it returns an instance of GeneratorWrapper<std::string>, which
|
||||
// is a value-wrapper around std::unique_ptr<IGenerator<std::string>>.
|
||||
Catch::Generators::GeneratorWrapper<std::string> lines(std::string /* ignored for example */) {
|
||||
return Catch::Generators::GeneratorWrapper<std::string>(
|
||||
std::unique_ptr<Catch::Generators::IGenerator<std::string>>(
|
||||
new LineGenerator()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("filter can convert types inside the generator expression", "[example][generator]") {
|
||||
auto num = GENERATE(map<int>([](std::string const& line) { return std::stoi(line); },
|
||||
lines("fake-file")));
|
||||
|
||||
REQUIRE(num > 0);
|
||||
}
|
||||
|
||||
// Compiling and running this file will result in 4 successful assertions
|
||||
54
libs/Catch2/examples/302-Gen-Table.cpp
Normal file
54
libs/Catch2/examples/302-Gen-Table.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// 302-Gen-Table.cpp
|
||||
// Shows how to use table to run a test many times with different inputs. Lifted from examples on
|
||||
// issue #850.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
#include <string>
|
||||
|
||||
struct TestSubject {
|
||||
// this is the method we are going to test. It returns the length of the
|
||||
// input string.
|
||||
size_t GetLength( const std::string& input ) const { return input.size(); }
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][generator]") {
|
||||
using std::make_tuple;
|
||||
// do setup here as normal
|
||||
TestSubject subj;
|
||||
|
||||
SECTION("This section is run for each row in the table") {
|
||||
std::string test_input;
|
||||
size_t expected_output;
|
||||
std::tie( test_input, expected_output ) =
|
||||
GENERATE( table<std::string, size_t>(
|
||||
{ /* In this case one of the parameters to our test case is the
|
||||
* expected output, but this is not required. There could be
|
||||
* multiple expected values in the table, which can have any
|
||||
* (fixed) number of columns.
|
||||
*/
|
||||
make_tuple( "one", 3 ),
|
||||
make_tuple( "two", 3 ),
|
||||
make_tuple( "three", 5 ),
|
||||
make_tuple( "four", 4 ) } ) );
|
||||
|
||||
// run the test
|
||||
auto result = subj.GetLength(test_input);
|
||||
// capture the input data to go with the outputs.
|
||||
CAPTURE(test_input);
|
||||
// check it matches the pre-calculated data
|
||||
REQUIRE(result == expected_output);
|
||||
} // end section
|
||||
}
|
||||
|
||||
/* Possible simplifications where less legacy toolchain support is needed:
|
||||
*
|
||||
* - With libstdc++6 or newer, the make_tuple() calls can be omitted
|
||||
* (technically C++17 but does not require -std in GCC/Clang). See
|
||||
* https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list
|
||||
*
|
||||
* - In C++17 mode std::tie() and the preceeding variable delcarations can be
|
||||
* replaced by structured bindings: auto [test_input, expected] = GENERATE(
|
||||
* table<std::string, size_t>({ ...
|
||||
*/
|
||||
// Compiling and running this file will result in 4 successful assertions
|
||||
33
libs/Catch2/examples/310-Gen-VariablesInGenerators.cpp
Normal file
33
libs/Catch2/examples/310-Gen-VariablesInGenerators.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// 310-Gen-VariablesInGenerator.cpp
|
||||
// Shows how to use variables when creating generators.
|
||||
|
||||
// Note that using variables inside generators is dangerous and should
|
||||
// be done only if you know what you are doing, because the generators
|
||||
// _WILL_ outlive the variables -- thus they should be either captured
|
||||
// by value directly, or copied by the generators during construction.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE("Generate random doubles across different ranges",
|
||||
"[generator][example][advanced]") {
|
||||
// Workaround for old libstdc++
|
||||
using record = std::tuple<double, double>;
|
||||
// Set up 3 ranges to generate numbers from
|
||||
auto r = GENERATE(table<double, double>({
|
||||
record{3, 4},
|
||||
record{-4, -3},
|
||||
record{10, 1000}
|
||||
}));
|
||||
|
||||
// This will not compile (intentionally), because it accesses a variable
|
||||
// auto number = GENERATE(take(50, random(std::get<0>(r), std::get<1>(r))));
|
||||
|
||||
// GENERATE_COPY copies all variables mentioned inside the expression
|
||||
// thus this will work.
|
||||
auto number = GENERATE_COPY(take(50, random(std::get<0>(r), std::get<1>(r))));
|
||||
|
||||
REQUIRE(std::abs(number) > 0);
|
||||
}
|
||||
|
||||
// Compiling and running this file will result in 150 successful assertions
|
||||
|
||||
41
libs/Catch2/examples/311-Gen-CustomCapture.cpp
Normal file
41
libs/Catch2/examples/311-Gen-CustomCapture.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// 311-Gen-CustomCapture.cpp
|
||||
// Shows how to provide custom capture list to the generator expression
|
||||
|
||||
// Note that using variables inside generators is dangerous and should
|
||||
// be done only if you know what you are doing, because the generators
|
||||
// _WILL_ outlive the variables. Also, even if you know what you are
|
||||
// doing, you should probably use GENERATE_COPY or GENERATE_REF macros
|
||||
// instead. However, if your use case requires having a
|
||||
// per-variable custom capture list, this example shows how to achieve
|
||||
// that.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE("Generate random doubles across different ranges",
|
||||
"[generator][example][advanced]") {
|
||||
// Workaround for old libstdc++
|
||||
using record = std::tuple<double, double>;
|
||||
// Set up 3 ranges to generate numbers from
|
||||
auto r1 = GENERATE(table<double, double>({
|
||||
record{3, 4},
|
||||
record{-4, -3},
|
||||
record{10, 1000}
|
||||
}));
|
||||
|
||||
auto r2(r1);
|
||||
|
||||
// This will take r1 by reference and r2 by value.
|
||||
// Note that there are no advantages for doing so in this example,
|
||||
// it is done only for expository purposes.
|
||||
auto number = Catch::Generators::generate( "custom capture generator", CATCH_INTERNAL_LINEINFO,
|
||||
[&r1, r2]{
|
||||
using namespace Catch::Generators;
|
||||
return makeGenerators(take(50, random(std::get<0>(r1), std::get<1>(r2))));
|
||||
}
|
||||
);
|
||||
|
||||
REQUIRE(std::abs(number) > 0);
|
||||
}
|
||||
|
||||
// Compiling and running this file will result in 150 successful assertions
|
||||
|
||||
158
libs/Catch2/examples/CMakeLists.txt
Normal file
158
libs/Catch2/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,158 @@
|
||||
#
|
||||
# Build examples.
|
||||
#
|
||||
# Requires CATCH_BUILD_EXAMPLES to be defined 'true', see ../CMakeLists.txt.
|
||||
#
|
||||
|
||||
cmake_minimum_required( VERSION 3.0 )
|
||||
|
||||
project( CatchExamples 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
|
||||
)
|
||||
|
||||
# multiple-file modules:
|
||||
|
||||
set( SOURCES_020
|
||||
020-TestCase-1.cpp
|
||||
020-TestCase-2.cpp
|
||||
)
|
||||
|
||||
# main for idiomatic test sources:
|
||||
|
||||
set( SOURCES_IDIOMATIC_MAIN
|
||||
000-CatchMain.cpp
|
||||
)
|
||||
|
||||
# sources to combine with 000-CatchMain.cpp:
|
||||
|
||||
set( SOURCES_IDIOMATIC_TESTS
|
||||
030-Asn-Require-Check.cpp
|
||||
100-Fix-Section.cpp
|
||||
110-Fix-ClassFixture.cpp
|
||||
120-Bdd-ScenarioGivenWhenThen.cpp
|
||||
210-Evt-EventListeners.cpp
|
||||
300-Gen-OwnGenerator.cpp
|
||||
301-Gen-MapTypeConversion.cpp
|
||||
302-Gen-Table.cpp
|
||||
310-Gen-VariablesInGenerators.cpp
|
||||
311-Gen-CustomCapture.cpp
|
||||
)
|
||||
|
||||
# main-s for reporter-specific test sources:
|
||||
|
||||
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 )
|
||||
endforeach()
|
||||
|
||||
# sources to combine with 200-Rpt-CatchMain{Reporter}.cpp:
|
||||
|
||||
set( SOURCES_REPORTERS_TESTS
|
||||
207-Rpt-TeamCityReporter.cpp
|
||||
)
|
||||
|
||||
# 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 $<TARGET_OBJECTS:CatchMain> ${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 $<TARGET_OBJECTS:CatchMainAutomake> ${HEADER_DIR}/catch2/catch.hpp )
|
||||
#add_executable( 207-Rpt-TapReporter ${EXAMPLES_DIR}/207-Rpt-TapReporter.cpp $<TARGET_OBJECTS:CatchMainTap> ${HEADER_DIR}/catch2/catch.hpp )
|
||||
add_executable( 207-Rpt-TeamCityReporter ${EXAMPLES_DIR}/207-Rpt-TeamCityReporter.cpp $<TARGET_OBJECTS:CatchMainTeamCity> ${HEADER_DIR}/catch2/catch.hpp )
|
||||
|
||||
#foreach( name ${TARGETS_REPORTERS_TESTS} )
|
||||
# add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
|
||||
#endforeach()
|
||||
|
||||
foreach( name ${TARGETS_ALL} )
|
||||
target_include_directories( ${name} PRIVATE ${HEADER_DIR} ${CATCH_DIR} )
|
||||
|
||||
set_property(TARGET ${name} PROPERTY CXX_STANDARD 11)
|
||||
set_property(TARGET ${name} PROPERTY CXX_EXTENSIONS OFF)
|
||||
|
||||
# Add desired warnings
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||
target_compile_options( ${name} PRIVATE -Wall -Wextra -Wunreachable-code )
|
||||
endif()
|
||||
# Clang specific warning go here
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
# Actually keep these
|
||||
target_compile_options( ${name} PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
||||
endif()
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||
target_compile_options( ${name} PRIVATE /W4 /w44265 /WX )
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
Reference in New Issue
Block a user